linux/drivers/hwmon/emc6w201.c
<<
>>
Prefs
   1/*
   2 * emc6w201.c - Hardware monitoring driver for the SMSC EMC6W201
   3 * Copyright (C) 2011  Jean Delvare <khali@linux-fr.org>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2 of the License, or
   8 * (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18 */
  19
  20#include <linux/module.h>
  21#include <linux/delay.h>
  22#include <linux/init.h>
  23#include <linux/slab.h>
  24#include <linux/jiffies.h>
  25#include <linux/i2c.h>
  26#include <linux/hwmon.h>
  27#include <linux/hwmon-sysfs.h>
  28#include <linux/err.h>
  29#include <linux/mutex.h>
  30
  31/*
  32 * Addresses to scan
  33 */
  34
  35static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
  36
  37/*
  38 * The EMC6W201 registers
  39 */
  40
  41#define EMC6W201_REG_IN(nr)             (0x20 + (nr))
  42#define EMC6W201_REG_TEMP(nr)           (0x26 + (nr))
  43#define EMC6W201_REG_FAN(nr)            (0x2C + (nr) * 2)
  44#define EMC6W201_REG_COMPANY            0x3E
  45#define EMC6W201_REG_VERSTEP            0x3F
  46#define EMC6W201_REG_CONFIG             0x40
  47#define EMC6W201_REG_IN_LOW(nr)         (0x4A + (nr) * 2)
  48#define EMC6W201_REG_IN_HIGH(nr)        (0x4B + (nr) * 2)
  49#define EMC6W201_REG_TEMP_LOW(nr)       (0x56 + (nr) * 2)
  50#define EMC6W201_REG_TEMP_HIGH(nr)      (0x57 + (nr) * 2)
  51#define EMC6W201_REG_FAN_MIN(nr)        (0x62 + (nr) * 2)
  52
  53enum { input, min, max } subfeature;
  54
  55/*
  56 * Per-device data
  57 */
  58
  59struct emc6w201_data {
  60        struct device *hwmon_dev;
  61        struct mutex update_lock;
  62        char valid; /* zero until following fields are valid */
  63        unsigned long last_updated; /* in jiffies */
  64
  65        /* registers values */
  66        u8 in[3][6];
  67        s8 temp[3][6];
  68        u16 fan[2][5];
  69};
  70
  71/*
  72 * Combine LSB and MSB registers in a single value
  73 * Locking: must be called with data->update_lock held
  74 */
  75static u16 emc6w201_read16(struct i2c_client *client, u8 reg)
  76{
  77        int lsb, msb;
  78
  79        lsb = i2c_smbus_read_byte_data(client, reg);
  80        msb = i2c_smbus_read_byte_data(client, reg + 1);
  81        if (unlikely(lsb < 0 || msb < 0)) {
  82                dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
  83                        16, "read", reg);
  84                return 0xFFFF;  /* Arbitrary value */
  85        }
  86
  87        return (msb << 8) | lsb;
  88}
  89
  90/*
  91 * Write 16-bit value to LSB and MSB registers
  92 * Locking: must be called with data->update_lock held
  93 */
  94static int emc6w201_write16(struct i2c_client *client, u8 reg, u16 val)
  95{
  96        int err;
  97
  98        err = i2c_smbus_write_byte_data(client, reg, val & 0xff);
  99        if (likely(!err))
 100                err = i2c_smbus_write_byte_data(client, reg + 1, val >> 8);
 101        if (unlikely(err < 0))
 102                dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
 103                        16, "write", reg);
 104
 105        return err;
 106}
 107
 108/* Read 8-bit value from register */
 109static u8 emc6w201_read8(struct i2c_client *client, u8 reg)
 110{
 111        int val;
 112
 113        val = i2c_smbus_read_byte_data(client, reg);
 114        if (unlikely(val < 0)) {
 115                dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
 116                        8, "read", reg);
 117                return 0x00;    /* Arbitrary value */
 118        }
 119
 120        return val;
 121}
 122
 123/* Write 8-bit value to register */
 124static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val)
 125{
 126        int err;
 127
 128        err = i2c_smbus_write_byte_data(client, reg, val);
 129        if (unlikely(err < 0))
 130                dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
 131                        8, "write", reg);
 132
 133        return err;
 134}
 135
 136static struct emc6w201_data *emc6w201_update_device(struct device *dev)
 137{
 138        struct i2c_client *client = to_i2c_client(dev);
 139        struct emc6w201_data *data = i2c_get_clientdata(client);
 140        int nr;
 141
 142        mutex_lock(&data->update_lock);
 143
 144        if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
 145                for (nr = 0; nr < 6; nr++) {
 146                        data->in[input][nr] =
 147                                emc6w201_read8(client,
 148                                                EMC6W201_REG_IN(nr));
 149                        data->in[min][nr] =
 150                                emc6w201_read8(client,
 151                                                EMC6W201_REG_IN_LOW(nr));
 152                        data->in[max][nr] =
 153                                emc6w201_read8(client,
 154                                                EMC6W201_REG_IN_HIGH(nr));
 155                }
 156
 157                for (nr = 0; nr < 6; nr++) {
 158                        data->temp[input][nr] =
 159                                emc6w201_read8(client,
 160                                                EMC6W201_REG_TEMP(nr));
 161                        data->temp[min][nr] =
 162                                emc6w201_read8(client,
 163                                                EMC6W201_REG_TEMP_LOW(nr));
 164                        data->temp[max][nr] =
 165                                emc6w201_read8(client,
 166                                                EMC6W201_REG_TEMP_HIGH(nr));
 167                }
 168
 169                for (nr = 0; nr < 5; nr++) {
 170                        data->fan[input][nr] =
 171                                emc6w201_read16(client,
 172                                                EMC6W201_REG_FAN(nr));
 173                        data->fan[min][nr] =
 174                                emc6w201_read16(client,
 175                                                EMC6W201_REG_FAN_MIN(nr));
 176                }
 177
 178                data->last_updated = jiffies;
 179                data->valid = 1;
 180        }
 181
 182        mutex_unlock(&data->update_lock);
 183
 184        return data;
 185}
 186
 187/*
 188 * Sysfs callback functions
 189 */
 190
 191static const u16 nominal_mv[6] = { 2500, 1500, 3300, 5000, 1500, 1500 };
 192
 193static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
 194        char *buf)
 195{
 196        struct emc6w201_data *data = emc6w201_update_device(dev);
 197        int sf = to_sensor_dev_attr_2(devattr)->index;
 198        int nr = to_sensor_dev_attr_2(devattr)->nr;
 199
 200        return sprintf(buf, "%u\n",
 201                       (unsigned)data->in[sf][nr] * nominal_mv[nr] / 0xC0);
 202}
 203
 204static ssize_t set_in(struct device *dev, struct device_attribute *devattr,
 205                      const char *buf, size_t count)
 206{
 207        struct i2c_client *client = to_i2c_client(dev);
 208        struct emc6w201_data *data = i2c_get_clientdata(client);
 209        int sf = to_sensor_dev_attr_2(devattr)->index;
 210        int nr = to_sensor_dev_attr_2(devattr)->nr;
 211        int err;
 212        long val;
 213        u8 reg;
 214
 215        err = kstrtol(buf, 10, &val);
 216        if (err < 0)
 217                return err;
 218
 219        val = DIV_ROUND_CLOSEST(val * 0xC0, nominal_mv[nr]);
 220        reg = (sf == min) ? EMC6W201_REG_IN_LOW(nr)
 221                          : EMC6W201_REG_IN_HIGH(nr);
 222
 223        mutex_lock(&data->update_lock);
 224        data->in[sf][nr] = SENSORS_LIMIT(val, 0, 255);
 225        err = emc6w201_write8(client, reg, data->in[sf][nr]);
 226        mutex_unlock(&data->update_lock);
 227
 228        return err < 0 ? err : count;
 229}
 230
 231static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
 232        char *buf)
 233{
 234        struct emc6w201_data *data = emc6w201_update_device(dev);
 235        int sf = to_sensor_dev_attr_2(devattr)->index;
 236        int nr = to_sensor_dev_attr_2(devattr)->nr;
 237
 238        return sprintf(buf, "%d\n", (int)data->temp[sf][nr] * 1000);
 239}
 240
 241static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
 242                        const char *buf, size_t count)
 243{
 244        struct i2c_client *client = to_i2c_client(dev);
 245        struct emc6w201_data *data = i2c_get_clientdata(client);
 246        int sf = to_sensor_dev_attr_2(devattr)->index;
 247        int nr = to_sensor_dev_attr_2(devattr)->nr;
 248        int err;
 249        long val;
 250        u8 reg;
 251
 252        err = kstrtol(buf, 10, &val);
 253        if (err < 0)
 254                return err;
 255
 256        val /= 1000;
 257        reg = (sf == min) ? EMC6W201_REG_TEMP_LOW(nr)
 258                          : EMC6W201_REG_TEMP_HIGH(nr);
 259
 260        mutex_lock(&data->update_lock);
 261        data->temp[sf][nr] = SENSORS_LIMIT(val, -127, 128);
 262        err = emc6w201_write8(client, reg, data->temp[sf][nr]);
 263        mutex_unlock(&data->update_lock);
 264
 265        return err < 0 ? err : count;
 266}
 267
 268static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
 269        char *buf)
 270{
 271        struct emc6w201_data *data = emc6w201_update_device(dev);
 272        int sf = to_sensor_dev_attr_2(devattr)->index;
 273        int nr = to_sensor_dev_attr_2(devattr)->nr;
 274        unsigned rpm;
 275
 276        if (data->fan[sf][nr] == 0 || data->fan[sf][nr] == 0xFFFF)
 277                rpm = 0;
 278        else
 279                rpm = 5400000U / data->fan[sf][nr];
 280
 281        return sprintf(buf, "%u\n", rpm);
 282}
 283
 284static ssize_t set_fan(struct device *dev, struct device_attribute *devattr,
 285                       const char *buf, size_t count)
 286{
 287        struct i2c_client *client = to_i2c_client(dev);
 288        struct emc6w201_data *data = i2c_get_clientdata(client);
 289        int sf = to_sensor_dev_attr_2(devattr)->index;
 290        int nr = to_sensor_dev_attr_2(devattr)->nr;
 291        int err;
 292        unsigned long val;
 293
 294        err = kstrtoul(buf, 10, &val);
 295        if (err < 0)
 296                return err;
 297
 298        if (val == 0) {
 299                val = 0xFFFF;
 300        } else {
 301                val = DIV_ROUND_CLOSEST(5400000U, val);
 302                val = SENSORS_LIMIT(val, 0, 0xFFFE);
 303        }
 304
 305        mutex_lock(&data->update_lock);
 306        data->fan[sf][nr] = val;
 307        err = emc6w201_write16(client, EMC6W201_REG_FAN_MIN(nr),
 308                               data->fan[sf][nr]);
 309        mutex_unlock(&data->update_lock);
 310
 311        return err < 0 ? err : count;
 312}
 313
 314static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, input);
 315static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, set_in,
 316                            0, min);
 317static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, set_in,
 318                            0, max);
 319static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, input);
 320static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_in, set_in,
 321                            1, min);
 322static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_in, set_in,
 323                            1, max);
 324static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, input);
 325static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, set_in,
 326                            2, min);
 327static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, set_in,
 328                            2, max);
 329static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, input);
 330static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, set_in,
 331                            3, min);
 332static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, set_in,
 333                            3, max);
 334static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, input);
 335static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, set_in,
 336                            4, min);
 337static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, set_in,
 338                            4, max);
 339static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 5, input);
 340static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_in, set_in,
 341                            5, min);
 342static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_in, set_in,
 343                            5, max);
 344
 345static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, input);
 346static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
 347                            0, min);
 348static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
 349                            0, max);
 350static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, input);
 351static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
 352                            1, min);
 353static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
 354                            1, max);
 355static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, input);
 356static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
 357                            2, min);
 358static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
 359                            2, max);
 360static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, input);
 361static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
 362                            3, min);
 363static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
 364                            3, max);
 365static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, input);
 366static SENSOR_DEVICE_ATTR_2(temp5_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
 367                            4, min);
 368static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
 369                            4, max);
 370static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, input);
 371static SENSOR_DEVICE_ATTR_2(temp6_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
 372                            5, min);
 373static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
 374                            5, max);
 375
 376static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, input);
 377static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
 378                            0, min);
 379static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 1, input);
 380static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
 381                            1, min);
 382static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 2, input);
 383static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
 384                            2, min);
 385static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 3, input);
 386static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
 387                            3, min);
 388static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, input);
 389static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
 390                            4, min);
 391
 392static struct attribute *emc6w201_attributes[] = {
 393        &sensor_dev_attr_in0_input.dev_attr.attr,
 394        &sensor_dev_attr_in0_min.dev_attr.attr,
 395        &sensor_dev_attr_in0_max.dev_attr.attr,
 396        &sensor_dev_attr_in1_input.dev_attr.attr,
 397        &sensor_dev_attr_in1_min.dev_attr.attr,
 398        &sensor_dev_attr_in1_max.dev_attr.attr,
 399        &sensor_dev_attr_in2_input.dev_attr.attr,
 400        &sensor_dev_attr_in2_min.dev_attr.attr,
 401        &sensor_dev_attr_in2_max.dev_attr.attr,
 402        &sensor_dev_attr_in3_input.dev_attr.attr,
 403        &sensor_dev_attr_in3_min.dev_attr.attr,
 404        &sensor_dev_attr_in3_max.dev_attr.attr,
 405        &sensor_dev_attr_in4_input.dev_attr.attr,
 406        &sensor_dev_attr_in4_min.dev_attr.attr,
 407        &sensor_dev_attr_in4_max.dev_attr.attr,
 408        &sensor_dev_attr_in5_input.dev_attr.attr,
 409        &sensor_dev_attr_in5_min.dev_attr.attr,
 410        &sensor_dev_attr_in5_max.dev_attr.attr,
 411
 412        &sensor_dev_attr_temp1_input.dev_attr.attr,
 413        &sensor_dev_attr_temp1_min.dev_attr.attr,
 414        &sensor_dev_attr_temp1_max.dev_attr.attr,
 415        &sensor_dev_attr_temp2_input.dev_attr.attr,
 416        &sensor_dev_attr_temp2_min.dev_attr.attr,
 417        &sensor_dev_attr_temp2_max.dev_attr.attr,
 418        &sensor_dev_attr_temp3_input.dev_attr.attr,
 419        &sensor_dev_attr_temp3_min.dev_attr.attr,
 420        &sensor_dev_attr_temp3_max.dev_attr.attr,
 421        &sensor_dev_attr_temp4_input.dev_attr.attr,
 422        &sensor_dev_attr_temp4_min.dev_attr.attr,
 423        &sensor_dev_attr_temp4_max.dev_attr.attr,
 424        &sensor_dev_attr_temp5_input.dev_attr.attr,
 425        &sensor_dev_attr_temp5_min.dev_attr.attr,
 426        &sensor_dev_attr_temp5_max.dev_attr.attr,
 427        &sensor_dev_attr_temp6_input.dev_attr.attr,
 428        &sensor_dev_attr_temp6_min.dev_attr.attr,
 429        &sensor_dev_attr_temp6_max.dev_attr.attr,
 430
 431        &sensor_dev_attr_fan1_input.dev_attr.attr,
 432        &sensor_dev_attr_fan1_min.dev_attr.attr,
 433        &sensor_dev_attr_fan2_input.dev_attr.attr,
 434        &sensor_dev_attr_fan2_min.dev_attr.attr,
 435        &sensor_dev_attr_fan3_input.dev_attr.attr,
 436        &sensor_dev_attr_fan3_min.dev_attr.attr,
 437        &sensor_dev_attr_fan4_input.dev_attr.attr,
 438        &sensor_dev_attr_fan4_min.dev_attr.attr,
 439        &sensor_dev_attr_fan5_input.dev_attr.attr,
 440        &sensor_dev_attr_fan5_min.dev_attr.attr,
 441        NULL
 442};
 443
 444static const struct attribute_group emc6w201_group = {
 445        .attrs = emc6w201_attributes,
 446};
 447
 448/*
 449 * Driver interface
 450 */
 451
 452/* Return 0 if detection is successful, -ENODEV otherwise */
 453static int emc6w201_detect(struct i2c_client *client,
 454                           struct i2c_board_info *info)
 455{
 456        struct i2c_adapter *adapter = client->adapter;
 457        int company, verstep, config;
 458
 459        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 460                return -ENODEV;
 461
 462        /* Identification */
 463        company = i2c_smbus_read_byte_data(client, EMC6W201_REG_COMPANY);
 464        if (company != 0x5C)
 465                return -ENODEV;
 466        verstep = i2c_smbus_read_byte_data(client, EMC6W201_REG_VERSTEP);
 467        if (verstep < 0 || (verstep & 0xF0) != 0xB0)
 468                return -ENODEV;
 469        if ((verstep & 0x0F) > 2) {
 470                dev_dbg(&client->dev, "Unknwown EMC6W201 stepping %d\n",
 471                        verstep & 0x0F);
 472                return -ENODEV;
 473        }
 474
 475        /* Check configuration */
 476        config = i2c_smbus_read_byte_data(client, EMC6W201_REG_CONFIG);
 477        if (config < 0 || (config & 0xF4) != 0x04)
 478                return -ENODEV;
 479        if (!(config & 0x01)) {
 480                dev_err(&client->dev, "Monitoring not enabled\n");
 481                return -ENODEV;
 482        }
 483
 484        strlcpy(info->type, "emc6w201", I2C_NAME_SIZE);
 485
 486        return 0;
 487}
 488
 489static int emc6w201_probe(struct i2c_client *client,
 490                          const struct i2c_device_id *id)
 491{
 492        struct emc6w201_data *data;
 493        int err;
 494
 495        data = devm_kzalloc(&client->dev, sizeof(struct emc6w201_data),
 496                            GFP_KERNEL);
 497        if (!data)
 498                return -ENOMEM;
 499
 500        i2c_set_clientdata(client, data);
 501        mutex_init(&data->update_lock);
 502
 503        /* Create sysfs attribute */
 504        err = sysfs_create_group(&client->dev.kobj, &emc6w201_group);
 505        if (err)
 506                return err;
 507
 508        /* Expose as a hwmon device */
 509        data->hwmon_dev = hwmon_device_register(&client->dev);
 510        if (IS_ERR(data->hwmon_dev)) {
 511                err = PTR_ERR(data->hwmon_dev);
 512                goto exit_remove;
 513        }
 514
 515        return 0;
 516
 517 exit_remove:
 518        sysfs_remove_group(&client->dev.kobj, &emc6w201_group);
 519        return err;
 520}
 521
 522static int emc6w201_remove(struct i2c_client *client)
 523{
 524        struct emc6w201_data *data = i2c_get_clientdata(client);
 525
 526        hwmon_device_unregister(data->hwmon_dev);
 527        sysfs_remove_group(&client->dev.kobj, &emc6w201_group);
 528
 529        return 0;
 530}
 531
 532static const struct i2c_device_id emc6w201_id[] = {
 533        { "emc6w201", 0 },
 534        { }
 535};
 536MODULE_DEVICE_TABLE(i2c, emc6w201_id);
 537
 538static struct i2c_driver emc6w201_driver = {
 539        .class          = I2C_CLASS_HWMON,
 540        .driver = {
 541                .name   = "emc6w201",
 542        },
 543        .probe          = emc6w201_probe,
 544        .remove         = emc6w201_remove,
 545        .id_table       = emc6w201_id,
 546        .detect         = emc6w201_detect,
 547        .address_list   = normal_i2c,
 548};
 549
 550module_i2c_driver(emc6w201_driver);
 551
 552MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
 553MODULE_DESCRIPTION("SMSC EMC6W201 hardware monitoring driver");
 554MODULE_LICENSE("GPL");
 555
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.