FROMLIST: ARM: dts: rockchip: enable hdmi audio on rk3036-kylin
[firefly-linux-kernel-4.4.55.git] / drivers / hwmon / max6650.c
index 0cafc390db4dd5fc1413ffe0814d6a15567dd352..162a520f4bd6a5627a8927d56d52ea6daaba9baf 100644 (file)
@@ -105,38 +105,13 @@ module_param(clock, int, S_IRUGO);
 
 #define DIV_FROM_REG(reg) (1 << (reg & 7))
 
-static int max6650_probe(struct i2c_client *client,
-                        const struct i2c_device_id *id);
-static int max6650_init_client(struct i2c_client *client);
-static int max6650_remove(struct i2c_client *client);
-static struct max6650_data *max6650_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static const struct i2c_device_id max6650_id[] = {
-       { "max6650", 1 },
-       { "max6651", 4 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, max6650_id);
-
-static struct i2c_driver max6650_driver = {
-       .driver = {
-               .name   = "max6650",
-       },
-       .probe          = max6650_probe,
-       .remove         = max6650_remove,
-       .id_table       = max6650_id,
-};
-
 /*
  * Client data (each client gets its own)
  */
 
 struct max6650_data {
-       struct device *hwmon_dev;
+       struct i2c_client *client;
+       const struct attribute_group *groups[3];
        struct mutex update_lock;
        int nr_fans;
        char valid; /* zero until following fields are valid */
@@ -151,6 +126,51 @@ struct max6650_data {
        u8 alarm;
 };
 
+static const u8 tach_reg[] = {
+       MAX6650_REG_TACH0,
+       MAX6650_REG_TACH1,
+       MAX6650_REG_TACH2,
+       MAX6650_REG_TACH3,
+};
+
+static struct max6650_data *max6650_update_device(struct device *dev)
+{
+       struct max6650_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
+       int i;
+
+       mutex_lock(&data->update_lock);
+
+       if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+               data->speed = i2c_smbus_read_byte_data(client,
+                                                      MAX6650_REG_SPEED);
+               data->config = i2c_smbus_read_byte_data(client,
+                                                       MAX6650_REG_CONFIG);
+               for (i = 0; i < data->nr_fans; i++) {
+                       data->tach[i] = i2c_smbus_read_byte_data(client,
+                                                                tach_reg[i]);
+               }
+               data->count = i2c_smbus_read_byte_data(client,
+                                                       MAX6650_REG_COUNT);
+               data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC);
+
+               /*
+                * Alarms are cleared on read in case the condition that
+                * caused the alarm is removed. Keep the value latched here
+                * for providing the register through different alarm files.
+                */
+               data->alarm |= i2c_smbus_read_byte_data(client,
+                                                       MAX6650_REG_ALARM);
+
+               data->last_updated = jiffies;
+               data->valid = 1;
+       }
+
+       mutex_unlock(&data->update_lock);
+
+       return data;
+}
+
 static ssize_t get_fan(struct device *dev, struct device_attribute *devattr,
                       char *buf)
 {
@@ -235,8 +255,8 @@ static ssize_t get_target(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_target(struct device *dev, struct device_attribute *devattr,
                         const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct max6650_data *data = i2c_get_clientdata(client);
+       struct max6650_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        int kscale, ktach;
        unsigned long rpm;
        int err;
@@ -304,8 +324,8 @@ static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
                        const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct max6650_data *data = i2c_get_clientdata(client);
+       struct max6650_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long pwm;
        int err;
 
@@ -350,8 +370,8 @@ static ssize_t get_enable(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_enable(struct device *dev, struct device_attribute *devattr,
                          const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct max6650_data *data = i2c_get_clientdata(client);
+       struct max6650_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        int max6650_modes[3] = {0, 3, 2};
        unsigned long mode;
        int err;
@@ -400,8 +420,8 @@ static ssize_t get_div(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_div(struct device *dev, struct device_attribute *devattr,
                       const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct max6650_data *data = i2c_get_clientdata(client);
+       struct max6650_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long div;
        int err;
 
@@ -446,7 +466,7 @@ static ssize_t get_alarm(struct device *dev, struct device_attribute *devattr,
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
        struct max6650_data *data = max6650_update_device(dev);
-       struct i2c_client *client = to_i2c_client(dev);
+       struct i2c_client *client = data->client;
        int alarm = 0;
 
        if (data->alarm & attr->index) {
@@ -484,7 +504,8 @@ static umode_t max6650_attrs_visible(struct kobject *kobj, struct attribute *a,
                                    int n)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
-       struct i2c_client *client = to_i2c_client(dev);
+       struct max6650_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        u8 alarm_en = i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN);
        struct device_attribute *devattr;
 
@@ -519,7 +540,7 @@ static struct attribute *max6650_attrs[] = {
        NULL
 };
 
-static struct attribute_group max6650_attr_grp = {
+static const struct attribute_group max6650_group = {
        .attrs = max6650_attrs,
        .is_visible = max6650_attrs_visible,
 };
@@ -531,7 +552,7 @@ static struct attribute *max6651_attrs[] = {
        NULL
 };
 
-static const struct attribute_group max6651_attr_grp = {
+static const struct attribute_group max6651_group = {
        .attrs = max6651_attrs,
 };
 
@@ -539,74 +560,17 @@ static const struct attribute_group max6651_attr_grp = {
  * Real code
  */
 
-static int max6650_probe(struct i2c_client *client,
-                        const struct i2c_device_id *id)
-{
-       struct max6650_data *data;
-       int err;
-
-       data = devm_kzalloc(&client->dev, sizeof(struct max6650_data),
-                           GFP_KERNEL);
-       if (!data) {
-               dev_err(&client->dev, "out of memory.\n");
-               return -ENOMEM;
-       }
-
-       i2c_set_clientdata(client, data);
-       mutex_init(&data->update_lock);
-       data->nr_fans = id->driver_data;
-
-       /*
-        * Initialize the max6650 chip
-        */
-       err = max6650_init_client(client);
-       if (err)
-               return err;
-
-       err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp);
-       if (err)
-               return err;
-       /* 3 additional fan inputs for the MAX6651 */
-       if (data->nr_fans == 4) {
-               err = sysfs_create_group(&client->dev.kobj, &max6651_attr_grp);
-               if (err)
-                       goto err_remove;
-       }
-
-       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");
-       if (data->nr_fans == 4)
-               sysfs_remove_group(&client->dev.kobj, &max6651_attr_grp);
-err_remove:
-       sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
-       return err;
-}
-
-static int max6650_remove(struct i2c_client *client)
+static int max6650_init_client(struct max6650_data *data,
+                              struct i2c_client *client)
 {
-       struct max6650_data *data = i2c_get_clientdata(client);
-
-       hwmon_device_unregister(data->hwmon_dev);
-       if (data->nr_fans == 4)
-               sysfs_remove_group(&client->dev.kobj, &max6651_attr_grp);
-       sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
-       return 0;
-}
-
-static int max6650_init_client(struct i2c_client *client)
-{
-       struct max6650_data *data = i2c_get_clientdata(client);
+       struct device *dev = &client->dev;
        int config;
        int err = -EIO;
 
        config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG);
 
        if (config < 0) {
-               dev_err(&client->dev, "Error reading config, aborting.\n");
+               dev_err(dev, "Error reading config, aborting.\n");
                return err;
        }
 
@@ -620,11 +584,11 @@ static int max6650_init_client(struct i2c_client *client)
                config |= MAX6650_CFG_V12;
                break;
        default:
-               dev_err(&client->dev, "illegal value for fan_voltage (%d)\n",
+               dev_err(dev, "illegal value for fan_voltage (%d)\n",
                        fan_voltage);
        }
 
-       dev_info(&client->dev, "Fan voltage is set to %dV.\n",
+       dev_info(dev, "Fan voltage is set to %dV.\n",
                 (config & MAX6650_CFG_V12) ? 12 : 5);
 
        switch (prescaler) {
@@ -650,11 +614,10 @@ static int max6650_init_client(struct i2c_client *client)
                         | MAX6650_CFG_PRESCALER_16;
                break;
        default:
-               dev_err(&client->dev, "illegal value for prescaler (%d)\n",
-                       prescaler);
+               dev_err(dev, "illegal value for prescaler (%d)\n", prescaler);
        }
 
-       dev_info(&client->dev, "Prescaler is set to %d.\n",
+       dev_info(dev, "Prescaler is set to %d.\n",
                 1 << (config & MAX6650_CFG_PRESCALER_MASK));
 
        /*
@@ -664,17 +627,17 @@ static int max6650_init_client(struct i2c_client *client)
         */
 
        if ((config & MAX6650_CFG_MODE_MASK) == MAX6650_CFG_MODE_OFF) {
-               dev_dbg(&client->dev, "Change mode to open loop, full off.\n");
+               dev_dbg(dev, "Change mode to open loop, full off.\n");
                config = (config & ~MAX6650_CFG_MODE_MASK)
                         | MAX6650_CFG_MODE_OPEN_LOOP;
                if (i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, 255)) {
-                       dev_err(&client->dev, "DAC write error, aborting.\n");
+                       dev_err(dev, "DAC write error, aborting.\n");
                        return err;
                }
        }
 
        if (i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, config)) {
-               dev_err(&client->dev, "Config write error, aborting.\n");
+               dev_err(dev, "Config write error, aborting.\n");
                return err;
        }
 
@@ -684,51 +647,55 @@ static int max6650_init_client(struct i2c_client *client)
        return 0;
 }
 
-static const u8 tach_reg[] = {
-       MAX6650_REG_TACH0,
-       MAX6650_REG_TACH1,
-       MAX6650_REG_TACH2,
-       MAX6650_REG_TACH3,
-};
-
-static struct max6650_data *max6650_update_device(struct device *dev)
+static int max6650_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
 {
-       int i;
-       struct i2c_client *client = to_i2c_client(dev);
-       struct max6650_data *data = i2c_get_clientdata(client);
-
-       mutex_lock(&data->update_lock);
+       struct device *dev = &client->dev;
+       struct max6650_data *data;
+       struct device *hwmon_dev;
+       int err;
 
-       if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
-               data->speed = i2c_smbus_read_byte_data(client,
-                                                      MAX6650_REG_SPEED);
-               data->config = i2c_smbus_read_byte_data(client,
-                                                       MAX6650_REG_CONFIG);
-               for (i = 0; i < data->nr_fans; i++) {
-                       data->tach[i] = i2c_smbus_read_byte_data(client,
-                                                                tach_reg[i]);
-               }
-               data->count = i2c_smbus_read_byte_data(client,
-                                                       MAX6650_REG_COUNT);
-               data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC);
+       data = devm_kzalloc(dev, sizeof(struct max6650_data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
-               /*
-                * Alarms are cleared on read in case the condition that
-                * caused the alarm is removed. Keep the value latched here
-                * for providing the register through different alarm files.
-                */
-               data->alarm |= i2c_smbus_read_byte_data(client,
-                                                       MAX6650_REG_ALARM);
+       data->client = client;
+       mutex_init(&data->update_lock);
+       data->nr_fans = id->driver_data;
 
-               data->last_updated = jiffies;
-               data->valid = 1;
-       }
+       /*
+        * Initialize the max6650 chip
+        */
+       err = max6650_init_client(data, client);
+       if (err)
+               return err;
 
-       mutex_unlock(&data->update_lock);
+       data->groups[0] = &max6650_group;
+       /* 3 additional fan inputs for the MAX6651 */
+       if (data->nr_fans == 4)
+               data->groups[1] = &max6651_group;
 
-       return data;
+       hwmon_dev = devm_hwmon_device_register_with_groups(dev,
+                                                          client->name, data,
+                                                          data->groups);
+       return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 
+static const struct i2c_device_id max6650_id[] = {
+       { "max6650", 1 },
+       { "max6651", 4 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, max6650_id);
+
+static struct i2c_driver max6650_driver = {
+       .driver = {
+               .name   = "max6650",
+       },
+       .probe          = max6650_probe,
+       .id_table       = max6650_id,
+};
+
 module_i2c_driver(max6650_driver);
 
 MODULE_AUTHOR("Hans J. Koch");