linux/drivers/hwmon/gl520sm.c
<<
>>
Prefs
   1/*
   2    gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware
   3                monitoring
   4    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
   5                              Kyösti Mälkki <kmalkki@cc.hut.fi>
   6    Copyright (c) 2005        Maarten Deprez <maartendeprez@users.sourceforge.net>
   7
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 2 of the License, or
  11    (at your option) any later version.
  12
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17
  18    You should have received a copy of the GNU General Public License
  19    along with this program; if not, write to the Free Software
  20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21
  22*/
  23
  24#include <linux/module.h>
  25#include <linux/init.h>
  26#include <linux/slab.h>
  27#include <linux/jiffies.h>
  28#include <linux/i2c.h>
  29#include <linux/hwmon.h>
  30#include <linux/hwmon-sysfs.h>
  31#include <linux/hwmon-vid.h>
  32#include <linux/err.h>
  33#include <linux/mutex.h>
  34#include <linux/sysfs.h>
  35
  36/* Type of the extra sensor */
  37static unsigned short extra_sensor_type;
  38module_param(extra_sensor_type, ushort, 0);
  39MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=temperature, 2=voltage)");
  40
  41/* Addresses to scan */
  42static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
  43
  44/* Insmod parameters */
  45I2C_CLIENT_INSMOD_1(gl520sm);
  46
  47/* Many GL520 constants specified below
  48One of the inputs can be configured as either temp or voltage.
  49That's why _TEMP2 and _IN4 access the same register
  50*/
  51
  52/* The GL520 registers */
  53#define GL520_REG_CHIP_ID               0x00
  54#define GL520_REG_REVISION              0x01
  55#define GL520_REG_CONF                  0x03
  56#define GL520_REG_MASK                  0x11
  57
  58#define GL520_REG_VID_INPUT             0x02
  59
  60static const u8 GL520_REG_IN_INPUT[]    = { 0x15, 0x14, 0x13, 0x0d, 0x0e };
  61static const u8 GL520_REG_IN_LIMIT[]    = { 0x0c, 0x09, 0x0a, 0x0b };
  62static const u8 GL520_REG_IN_MIN[]      = { 0x0c, 0x09, 0x0a, 0x0b, 0x18 };
  63static const u8 GL520_REG_IN_MAX[]      = { 0x0c, 0x09, 0x0a, 0x0b, 0x17 };
  64
  65static const u8 GL520_REG_TEMP_INPUT[]          = { 0x04, 0x0e };
  66static const u8 GL520_REG_TEMP_MAX[]            = { 0x05, 0x17 };
  67static const u8 GL520_REG_TEMP_MAX_HYST[]       = { 0x06, 0x18 };
  68
  69#define GL520_REG_FAN_INPUT             0x07
  70#define GL520_REG_FAN_MIN               0x08
  71#define GL520_REG_FAN_DIV               0x0f
  72#define GL520_REG_FAN_OFF               GL520_REG_FAN_DIV
  73
  74#define GL520_REG_ALARMS                0x12
  75#define GL520_REG_BEEP_MASK             0x10
  76#define GL520_REG_BEEP_ENABLE           GL520_REG_CONF
  77
  78/*
  79 * Function declarations
  80 */
  81
  82static int gl520_probe(struct i2c_client *client,
  83                       const struct i2c_device_id *id);
  84static int gl520_detect(struct i2c_client *client, int kind,
  85                        struct i2c_board_info *info);
  86static void gl520_init_client(struct i2c_client *client);
  87static int gl520_remove(struct i2c_client *client);
  88static int gl520_read_value(struct i2c_client *client, u8 reg);
  89static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value);
  90static struct gl520_data *gl520_update_device(struct device *dev);
  91
  92/* Driver data */
  93static const struct i2c_device_id gl520_id[] = {
  94        { "gl520sm", gl520sm },
  95        { }
  96};
  97MODULE_DEVICE_TABLE(i2c, gl520_id);
  98
  99static struct i2c_driver gl520_driver = {
 100        .class          = I2C_CLASS_HWMON,
 101        .driver = {
 102                .name   = "gl520sm",
 103        },
 104        .probe          = gl520_probe,
 105        .remove         = gl520_remove,
 106        .id_table       = gl520_id,
 107        .detect         = gl520_detect,
 108        .address_data   = &addr_data,
 109};
 110
 111/* Client data */
 112struct gl520_data {
 113        struct device *hwmon_dev;
 114        struct mutex update_lock;
 115        char valid;             /* zero until the following fields are valid */
 116        unsigned long last_updated;     /* in jiffies */
 117
 118        u8 vid;
 119        u8 vrm;
 120        u8 in_input[5];         /* [0] = VVD */
 121        u8 in_min[5];           /* [0] = VDD */
 122        u8 in_max[5];           /* [0] = VDD */
 123        u8 fan_input[2];
 124        u8 fan_min[2];
 125        u8 fan_div[2];
 126        u8 fan_off;
 127        u8 temp_input[2];
 128        u8 temp_max[2];
 129        u8 temp_max_hyst[2];
 130        u8 alarms;
 131        u8 beep_enable;
 132        u8 beep_mask;
 133        u8 alarm_mask;
 134        u8 two_temps;
 135};
 136
 137/*
 138 * Sysfs stuff
 139 */
 140
 141static ssize_t get_cpu_vid(struct device *dev, struct device_attribute *attr,
 142                           char *buf)
 143{
 144        struct gl520_data *data = gl520_update_device(dev);
 145        return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
 146}
 147static DEVICE_ATTR(cpu0_vid, S_IRUGO, get_cpu_vid, NULL);
 148
 149#define VDD_FROM_REG(val) (((val)*95+2)/4)
 150#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255))
 151
 152#define IN_FROM_REG(val) ((val)*19)
 153#define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255))
 154
 155static ssize_t get_in_input(struct device *dev, struct device_attribute *attr,
 156                            char *buf)
 157{
 158        int n = to_sensor_dev_attr(attr)->index;
 159        struct gl520_data *data = gl520_update_device(dev);
 160        u8 r = data->in_input[n];
 161
 162        if (n == 0)
 163                return sprintf(buf, "%d\n", VDD_FROM_REG(r));
 164        else
 165                return sprintf(buf, "%d\n", IN_FROM_REG(r));
 166}
 167
 168static ssize_t get_in_min(struct device *dev, struct device_attribute *attr,
 169                          char *buf)
 170{
 171        int n = to_sensor_dev_attr(attr)->index;
 172        struct gl520_data *data = gl520_update_device(dev);
 173        u8 r = data->in_min[n];
 174
 175        if (n == 0)
 176                return sprintf(buf, "%d\n", VDD_FROM_REG(r));
 177        else
 178                return sprintf(buf, "%d\n", IN_FROM_REG(r));
 179}
 180
 181static ssize_t get_in_max(struct device *dev, struct device_attribute *attr,
 182                          char *buf)
 183{
 184        int n = to_sensor_dev_attr(attr)->index;
 185        struct gl520_data *data = gl520_update_device(dev);
 186        u8 r = data->in_max[n];
 187
 188        if (n == 0)
 189                return sprintf(buf, "%d\n", VDD_FROM_REG(r));
 190        else
 191                return sprintf(buf, "%d\n", IN_FROM_REG(r));
 192}
 193
 194static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 195                          const char *buf, size_t count)
 196{
 197        struct i2c_client *client = to_i2c_client(dev);
 198        struct gl520_data *data = i2c_get_clientdata(client);
 199        int n = to_sensor_dev_attr(attr)->index;
 200        long v = simple_strtol(buf, NULL, 10);
 201        u8 r;
 202
 203        mutex_lock(&data->update_lock);
 204
 205        if (n == 0)
 206                r = VDD_TO_REG(v);
 207        else
 208                r = IN_TO_REG(v);
 209
 210        data->in_min[n] = r;
 211
 212        if (n < 4)
 213                gl520_write_value(client, GL520_REG_IN_MIN[n],
 214                                  (gl520_read_value(client, GL520_REG_IN_MIN[n])
 215                                   & ~0xff) | r);
 216        else
 217                gl520_write_value(client, GL520_REG_IN_MIN[n], r);
 218
 219        mutex_unlock(&data->update_lock);
 220        return count;
 221}
 222
 223static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 224                          const char *buf, size_t count)
 225{
 226        struct i2c_client *client = to_i2c_client(dev);
 227        struct gl520_data *data = i2c_get_clientdata(client);
 228        int n = to_sensor_dev_attr(attr)->index;
 229        long v = simple_strtol(buf, NULL, 10);
 230        u8 r;
 231
 232        if (n == 0)
 233                r = VDD_TO_REG(v);
 234        else
 235                r = IN_TO_REG(v);
 236
 237        mutex_lock(&data->update_lock);
 238
 239        data->in_max[n] = r;
 240
 241        if (n < 4)
 242                gl520_write_value(client, GL520_REG_IN_MAX[n],
 243                                  (gl520_read_value(client, GL520_REG_IN_MAX[n])
 244                                   & ~0xff00) | (r << 8));
 245        else
 246                gl520_write_value(client, GL520_REG_IN_MAX[n], r);
 247
 248        mutex_unlock(&data->update_lock);
 249        return count;
 250}
 251
 252static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, get_in_input, NULL, 0);
 253static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, get_in_input, NULL, 1);
 254static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, get_in_input, NULL, 2);
 255static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, get_in_input, NULL, 3);
 256static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, get_in_input, NULL, 4);
 257static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR,
 258                get_in_min, set_in_min, 0);
 259static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO | S_IWUSR,
 260                get_in_min, set_in_min, 1);
 261static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO | S_IWUSR,
 262                get_in_min, set_in_min, 2);
 263static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO | S_IWUSR,
 264                get_in_min, set_in_min, 3);
 265static SENSOR_DEVICE_ATTR(in4_min, S_IRUGO | S_IWUSR,
 266                get_in_min, set_in_min, 4);
 267static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR,
 268                get_in_max, set_in_max, 0);
 269static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR,
 270                get_in_max, set_in_max, 1);
 271static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO | S_IWUSR,
 272                get_in_max, set_in_max, 2);
 273static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO | S_IWUSR,
 274                get_in_max, set_in_max, 3);
 275static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR,
 276                get_in_max, set_in_max, 4);
 277
 278#define DIV_FROM_REG(val) (1 << (val))
 279#define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val) << (div))))
 280#define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255));
 281
 282static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr,
 283                             char *buf)
 284{
 285        int n = to_sensor_dev_attr(attr)->index;
 286        struct gl520_data *data = gl520_update_device(dev);
 287
 288        return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_input[n],
 289                                                 data->fan_div[n]));
 290}
 291
 292static ssize_t get_fan_min(struct device *dev, struct device_attribute *attr,
 293                           char *buf)
 294{
 295        int n = to_sensor_dev_attr(attr)->index;
 296        struct gl520_data *data = gl520_update_device(dev);
 297
 298        return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[n],
 299                                                 data->fan_div[n]));
 300}
 301
 302static ssize_t get_fan_div(struct device *dev, struct device_attribute *attr,
 303                           char *buf)
 304{
 305        int n = to_sensor_dev_attr(attr)->index;
 306        struct gl520_data *data = gl520_update_device(dev);
 307
 308        return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[n]));
 309}
 310
 311static ssize_t get_fan_off(struct device *dev, struct device_attribute *attr,
 312                           char *buf)
 313{
 314        struct gl520_data *data = gl520_update_device(dev);
 315        return sprintf(buf, "%d\n", data->fan_off);
 316}
 317
 318static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 319                           const char *buf, size_t count)
 320{
 321        struct i2c_client *client = to_i2c_client(dev);
 322        struct gl520_data *data = i2c_get_clientdata(client);
 323        int n = to_sensor_dev_attr(attr)->index;
 324        unsigned long v = simple_strtoul(buf, NULL, 10);
 325        u8 r;
 326
 327        mutex_lock(&data->update_lock);
 328        r = FAN_TO_REG(v, data->fan_div[n]);
 329        data->fan_min[n] = r;
 330
 331        if (n == 0)
 332                gl520_write_value(client, GL520_REG_FAN_MIN,
 333                                  (gl520_read_value(client, GL520_REG_FAN_MIN)
 334                                   & ~0xff00) | (r << 8));
 335        else
 336                gl520_write_value(client, GL520_REG_FAN_MIN,
 337                                  (gl520_read_value(client, GL520_REG_FAN_MIN)
 338                                   & ~0xff) | r);
 339
 340        data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
 341        if (data->fan_min[n] == 0)
 342                data->alarm_mask &= (n == 0) ? ~0x20 : ~0x40;
 343        else
 344                data->alarm_mask |= (n == 0) ? 0x20 : 0x40;
 345        data->beep_mask &= data->alarm_mask;
 346        gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
 347
 348        mutex_unlock(&data->update_lock);
 349        return count;
 350}
 351
 352static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 353                           const char *buf, size_t count)
 354{
 355        struct i2c_client *client = to_i2c_client(dev);
 356        struct gl520_data *data = i2c_get_clientdata(client);
 357        int n = to_sensor_dev_attr(attr)->index;
 358        unsigned long v = simple_strtoul(buf, NULL, 10);
 359        u8 r;
 360
 361        switch (v) {
 362        case 1: r = 0; break;
 363        case 2: r = 1; break;
 364        case 4: r = 2; break;
 365        case 8: r = 3; break;
 366        default:
 367                dev_err(&client->dev, "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v);
 368                return -EINVAL;
 369        }
 370
 371        mutex_lock(&data->update_lock);
 372        data->fan_div[n] = r;
 373
 374        if (n == 0)
 375                gl520_write_value(client, GL520_REG_FAN_DIV,
 376                                  (gl520_read_value(client, GL520_REG_FAN_DIV)
 377                                   & ~0xc0) | (r << 6));
 378        else
 379                gl520_write_value(client, GL520_REG_FAN_DIV,
 380                                  (gl520_read_value(client, GL520_REG_FAN_DIV)
 381                                   & ~0x30) | (r << 4));
 382
 383        mutex_unlock(&data->update_lock);
 384        return count;
 385}
 386
 387static ssize_t set_fan_off(struct device *dev, struct device_attribute *attr,
 388                           const char *buf, size_t count)
 389{
 390        struct i2c_client *client = to_i2c_client(dev);
 391        struct gl520_data *data = i2c_get_clientdata(client);
 392        u8 r = simple_strtoul(buf, NULL, 10)?1:0;
 393
 394        mutex_lock(&data->update_lock);
 395        data->fan_off = r;
 396        gl520_write_value(client, GL520_REG_FAN_OFF,
 397                          (gl520_read_value(client, GL520_REG_FAN_OFF)
 398                           & ~0x0c) | (r << 2));
 399        mutex_unlock(&data->update_lock);
 400        return count;
 401}
 402
 403static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan_input, NULL, 0);
 404static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan_input, NULL, 1);
 405static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR,
 406                get_fan_min, set_fan_min, 0);
 407static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR,
 408                get_fan_min, set_fan_min, 1);
 409static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
 410                get_fan_div, set_fan_div, 0);
 411static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
 412                get_fan_div, set_fan_div, 1);
 413static DEVICE_ATTR(fan1_off, S_IRUGO | S_IWUSR,
 414                get_fan_off, set_fan_off);
 415
 416#define TEMP_FROM_REG(val) (((val) - 130) * 1000)
 417#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-500:(val)+500) / 1000)+130),0,255))
 418
 419static ssize_t get_temp_input(struct device *dev, struct device_attribute *attr,
 420                              char *buf)
 421{
 422        int n = to_sensor_dev_attr(attr)->index;
 423        struct gl520_data *data = gl520_update_device(dev);
 424
 425        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_input[n]));
 426}
 427
 428static ssize_t get_temp_max(struct device *dev, struct device_attribute *attr,
 429                            char *buf)
 430{
 431        int n = to_sensor_dev_attr(attr)->index;
 432        struct gl520_data *data = gl520_update_device(dev);
 433
 434        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[n]));
 435}
 436
 437static ssize_t get_temp_max_hyst(struct device *dev, struct device_attribute
 438                                 *attr, char *buf)
 439{
 440        int n = to_sensor_dev_attr(attr)->index;
 441        struct gl520_data *data = gl520_update_device(dev);
 442
 443        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max_hyst[n]));
 444}
 445
 446static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 447                            const char *buf, size_t count)
 448{
 449        struct i2c_client *client = to_i2c_client(dev);
 450        struct gl520_data *data = i2c_get_clientdata(client);
 451        int n = to_sensor_dev_attr(attr)->index;
 452        long v = simple_strtol(buf, NULL, 10);
 453
 454        mutex_lock(&data->update_lock);
 455        data->temp_max[n] = TEMP_TO_REG(v);
 456        gl520_write_value(client, GL520_REG_TEMP_MAX[n], data->temp_max[n]);
 457        mutex_unlock(&data->update_lock);
 458        return count;
 459}
 460
 461static ssize_t set_temp_max_hyst(struct device *dev, struct device_attribute
 462                                 *attr, const char *buf, size_t count)
 463{
 464        struct i2c_client *client = to_i2c_client(dev);
 465        struct gl520_data *data = i2c_get_clientdata(client);
 466        int n = to_sensor_dev_attr(attr)->index;
 467        long v = simple_strtol(buf, NULL, 10);
 468
 469        mutex_lock(&data->update_lock);
 470        data->temp_max_hyst[n] = TEMP_TO_REG(v);
 471        gl520_write_value(client, GL520_REG_TEMP_MAX_HYST[n],
 472                          data->temp_max_hyst[n]);
 473        mutex_unlock(&data->update_lock);
 474        return count;
 475}
 476
 477static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_temp_input, NULL, 0);
 478static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_temp_input, NULL, 1);
 479static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
 480                get_temp_max, set_temp_max, 0);
 481static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR,
 482                get_temp_max, set_temp_max, 1);
 483static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
 484                get_temp_max_hyst, set_temp_max_hyst, 0);
 485static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR,
 486                get_temp_max_hyst, set_temp_max_hyst, 1);
 487
 488static ssize_t get_alarms(struct device *dev, struct device_attribute *attr,
 489                          char *buf)
 490{
 491        struct gl520_data *data = gl520_update_device(dev);
 492        return sprintf(buf, "%d\n", data->alarms);
 493}
 494
 495static ssize_t get_beep_enable(struct device *dev, struct device_attribute
 496                               *attr, char *buf)
 497{
 498        struct gl520_data *data = gl520_update_device(dev);
 499        return sprintf(buf, "%d\n", data->beep_enable);
 500}
 501
 502static ssize_t get_beep_mask(struct device *dev, struct device_attribute *attr,
 503                             char *buf)
 504{
 505        struct gl520_data *data = gl520_update_device(dev);
 506        return sprintf(buf, "%d\n", data->beep_mask);
 507}
 508
 509static ssize_t set_beep_enable(struct device *dev, struct device_attribute
 510                               *attr, const char *buf, size_t count)
 511{
 512        struct i2c_client *client = to_i2c_client(dev);
 513        struct gl520_data *data = i2c_get_clientdata(client);
 514        u8 r = simple_strtoul(buf, NULL, 10)?0:1;
 515
 516        mutex_lock(&data->update_lock);
 517        data->beep_enable = !r;
 518        gl520_write_value(client, GL520_REG_BEEP_ENABLE,
 519                          (gl520_read_value(client, GL520_REG_BEEP_ENABLE)
 520                           & ~0x04) | (r << 2));
 521        mutex_unlock(&data->update_lock);
 522        return count;
 523}
 524
 525static ssize_t set_beep_mask(struct device *dev, struct device_attribute *attr,
 526                             const char *buf, size_t count)
 527{
 528        struct i2c_client *client = to_i2c_client(dev);
 529        struct gl520_data *data = i2c_get_clientdata(client);
 530        u8 r = simple_strtoul(buf, NULL, 10);
 531
 532        mutex_lock(&data->update_lock);
 533        r &= data->alarm_mask;
 534        data->beep_mask = r;
 535        gl520_write_value(client, GL520_REG_BEEP_MASK, r);
 536        mutex_unlock(&data->update_lock);
 537        return count;
 538}
 539
 540static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
 541static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR,
 542                get_beep_enable, set_beep_enable);
 543static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR,
 544                get_beep_mask, set_beep_mask);
 545
 546static ssize_t get_alarm(struct device *dev, struct device_attribute *attr,
 547                         char *buf)
 548{
 549        int bit_nr = to_sensor_dev_attr(attr)->index;
 550        struct gl520_data *data = gl520_update_device(dev);
 551
 552        return sprintf(buf, "%d\n", (data->alarms >> bit_nr) & 1);
 553}
 554
 555static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, get_alarm, NULL, 0);
 556static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, get_alarm, NULL, 1);
 557static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, get_alarm, NULL, 2);
 558static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, get_alarm, NULL, 3);
 559static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, get_alarm, NULL, 4);
 560static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, get_alarm, NULL, 5);
 561static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, get_alarm, NULL, 6);
 562static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, get_alarm, NULL, 7);
 563static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, get_alarm, NULL, 7);
 564
 565static ssize_t get_beep(struct device *dev, struct device_attribute *attr,
 566                        char *buf)
 567{
 568        int bitnr = to_sensor_dev_attr(attr)->index;
 569        struct gl520_data *data = gl520_update_device(dev);
 570
 571        return sprintf(buf, "%d\n", (data->beep_mask >> bitnr) & 1);
 572}
 573
 574static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
 575                        const char *buf, size_t count)
 576{
 577        struct i2c_client *client = to_i2c_client(dev);
 578        struct gl520_data *data = i2c_get_clientdata(client);
 579        int bitnr = to_sensor_dev_attr(attr)->index;
 580        unsigned long bit;
 581
 582        bit = simple_strtoul(buf, NULL, 10);
 583        if (bit & ~1)
 584                return -EINVAL;
 585
 586        mutex_lock(&data->update_lock);
 587        data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
 588        if (bit)
 589                data->beep_mask |= (1 << bitnr);
 590        else
 591                data->beep_mask &= ~(1 << bitnr);
 592        gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
 593        mutex_unlock(&data->update_lock);
 594        return count;
 595}
 596
 597static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR, get_beep, set_beep, 0);
 598static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO | S_IWUSR, get_beep, set_beep, 1);
 599static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO | S_IWUSR, get_beep, set_beep, 2);
 600static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO | S_IWUSR, get_beep, set_beep, 3);
 601static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR, get_beep, set_beep, 4);
 602static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO | S_IWUSR, get_beep, set_beep, 5);
 603static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO | S_IWUSR, get_beep, set_beep, 6);
 604static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO | S_IWUSR, get_beep, set_beep, 7);
 605static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO | S_IWUSR, get_beep, set_beep, 7);
 606
 607static struct attribute *gl520_attributes[] = {
 608        &dev_attr_cpu0_vid.attr,
 609
 610        &sensor_dev_attr_in0_input.dev_attr.attr,
 611        &sensor_dev_attr_in0_min.dev_attr.attr,
 612        &sensor_dev_attr_in0_max.dev_attr.attr,
 613        &sensor_dev_attr_in0_alarm.dev_attr.attr,
 614        &sensor_dev_attr_in0_beep.dev_attr.attr,
 615        &sensor_dev_attr_in1_input.dev_attr.attr,
 616        &sensor_dev_attr_in1_min.dev_attr.attr,
 617        &sensor_dev_attr_in1_max.dev_attr.attr,
 618        &sensor_dev_attr_in1_alarm.dev_attr.attr,
 619        &sensor_dev_attr_in1_beep.dev_attr.attr,
 620        &sensor_dev_attr_in2_input.dev_attr.attr,
 621        &sensor_dev_attr_in2_min.dev_attr.attr,
 622        &sensor_dev_attr_in2_max.dev_attr.attr,
 623        &sensor_dev_attr_in2_alarm.dev_attr.attr,
 624        &sensor_dev_attr_in2_beep.dev_attr.attr,
 625        &sensor_dev_attr_in3_input.dev_attr.attr,
 626        &sensor_dev_attr_in3_min.dev_attr.attr,
 627        &sensor_dev_attr_in3_max.dev_attr.attr,
 628        &sensor_dev_attr_in3_alarm.dev_attr.attr,
 629        &sensor_dev_attr_in3_beep.dev_attr.attr,
 630
 631        &sensor_dev_attr_fan1_input.dev_attr.attr,
 632        &sensor_dev_attr_fan1_min.dev_attr.attr,
 633        &sensor_dev_attr_fan1_div.dev_attr.attr,
 634        &sensor_dev_attr_fan1_alarm.dev_attr.attr,
 635        &sensor_dev_attr_fan1_beep.dev_attr.attr,
 636        &dev_attr_fan1_off.attr,
 637        &sensor_dev_attr_fan2_input.dev_attr.attr,
 638        &sensor_dev_attr_fan2_min.dev_attr.attr,
 639        &sensor_dev_attr_fan2_div.dev_attr.attr,
 640        &sensor_dev_attr_fan2_alarm.dev_attr.attr,
 641        &sensor_dev_attr_fan2_beep.dev_attr.attr,
 642
 643        &sensor_dev_attr_temp1_input.dev_attr.attr,
 644        &sensor_dev_attr_temp1_max.dev_attr.attr,
 645        &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 646        &sensor_dev_attr_temp1_alarm.dev_attr.attr,
 647        &sensor_dev_attr_temp1_beep.dev_attr.attr,
 648
 649        &dev_attr_alarms.attr,
 650        &dev_attr_beep_enable.attr,
 651        &dev_attr_beep_mask.attr,
 652        NULL
 653};
 654
 655static const struct attribute_group gl520_group = {
 656        .attrs = gl520_attributes,
 657};
 658
 659static struct attribute *gl520_attributes_opt[] = {
 660        &sensor_dev_attr_in4_input.dev_attr.attr,
 661        &sensor_dev_attr_in4_min.dev_attr.attr,
 662        &sensor_dev_attr_in4_max.dev_attr.attr,
 663        &sensor_dev_attr_in4_alarm.dev_attr.attr,
 664        &sensor_dev_attr_in4_beep.dev_attr.attr,
 665
 666        &sensor_dev_attr_temp2_input.dev_attr.attr,
 667        &sensor_dev_attr_temp2_max.dev_attr.attr,
 668        &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
 669        &sensor_dev_attr_temp2_alarm.dev_attr.attr,
 670        &sensor_dev_attr_temp2_beep.dev_attr.attr,
 671        NULL
 672};
 673
 674static const struct attribute_group gl520_group_opt = {
 675        .attrs = gl520_attributes_opt,
 676};
 677
 678
 679/*
 680 * Real code
 681 */
 682
 683/* Return 0 if detection is successful, -ENODEV otherwise */
 684static int gl520_detect(struct i2c_client *client, int kind,
 685                        struct i2c_board_info *info)
 686{
 687        struct i2c_adapter *adapter = client->adapter;
 688
 689        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 690                                     I2C_FUNC_SMBUS_WORD_DATA))
 691                return -ENODEV;
 692
 693        /* Determine the chip type. */
 694        if (kind < 0) {
 695                if ((gl520_read_value(client, GL520_REG_CHIP_ID) != 0x20) ||
 696                    ((gl520_read_value(client, GL520_REG_REVISION) & 0x7f) != 0x00) ||
 697                    ((gl520_read_value(client, GL520_REG_CONF) & 0x80) != 0x00)) {
 698                        dev_dbg(&client->dev, "Unknown chip type, skipping\n");
 699                        return -ENODEV;
 700                }
 701        }
 702
 703        strlcpy(info->type, "gl520sm", I2C_NAME_SIZE);
 704
 705        return 0;
 706}
 707
 708static int gl520_probe(struct i2c_client *client,
 709                       const struct i2c_device_id *id)
 710{
 711        struct gl520_data *data;
 712        int err;
 713
 714        data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL);
 715        if (!data) {
 716                err = -ENOMEM;
 717                goto exit;
 718        }
 719
 720        i2c_set_clientdata(client, data);
 721        mutex_init(&data->update_lock);
 722
 723        /* Initialize the GL520SM chip */
 724        gl520_init_client(client);
 725
 726        /* Register sysfs hooks */
 727        if ((err = sysfs_create_group(&client->dev.kobj, &gl520_group)))
 728                goto exit_free;
 729
 730        if (data->two_temps) {
 731                if ((err = device_create_file(&client->dev,
 732                                &sensor_dev_attr_temp2_input.dev_attr))
 733                 || (err = device_create_file(&client->dev,
 734                                &sensor_dev_attr_temp2_max.dev_attr))
 735                 || (err = device_create_file(&client->dev,
 736                                &sensor_dev_attr_temp2_max_hyst.dev_attr))
 737                 || (err = device_create_file(&client->dev,
 738                                &sensor_dev_attr_temp2_alarm.dev_attr))
 739                 || (err = device_create_file(&client->dev,
 740                                &sensor_dev_attr_temp2_beep.dev_attr)))
 741                        goto exit_remove_files;
 742        } else {
 743                if ((err = device_create_file(&client->dev,
 744                                &sensor_dev_attr_in4_input.dev_attr))
 745                 || (err = device_create_file(&client->dev,
 746                                &sensor_dev_attr_in4_min.dev_attr))
 747                 || (err = device_create_file(&client->dev,
 748                                &sensor_dev_attr_in4_max.dev_attr))
 749                 || (err = device_create_file(&client->dev,
 750                                &sensor_dev_attr_in4_alarm.dev_attr))
 751                 || (err = device_create_file(&client->dev,
 752                                &sensor_dev_attr_in4_beep.dev_attr)))
 753                        goto exit_remove_files;
 754        }
 755
 756
 757        data->hwmon_dev = hwmon_device_register(&client->dev);
 758        if (IS_ERR(data->hwmon_dev)) {
 759                err = PTR_ERR(data->hwmon_dev);
 760                goto exit_remove_files;
 761        }
 762
 763        return 0;
 764
 765exit_remove_files:
 766        sysfs_remove_group(&client->dev.kobj, &gl520_group);
 767        sysfs_remove_group(&client->dev.kobj, &gl520_group_opt);
 768exit_free:
 769        kfree(data);
 770exit:
 771        return err;
 772}
 773
 774
 775/* Called when we have found a new GL520SM. */
 776static void gl520_init_client(struct i2c_client *client)
 777{
 778        struct gl520_data *data = i2c_get_clientdata(client);
 779        u8 oldconf, conf;
 780
 781        conf = oldconf = gl520_read_value(client, GL520_REG_CONF);
 782
 783        data->alarm_mask = 0xff;
 784        data->vrm = vid_which_vrm();
 785
 786        if (extra_sensor_type == 1)
 787                conf &= ~0x10;
 788        else if (extra_sensor_type == 2)
 789                conf |= 0x10;
 790        data->two_temps = !(conf & 0x10);
 791
 792        /* If IRQ# is disabled, we can safely force comparator mode */
 793        if (!(conf & 0x20))
 794                conf &= 0xf7;
 795
 796        /* Enable monitoring if needed */
 797        conf |= 0x40;
 798
 799        if (conf != oldconf)
 800                gl520_write_value(client, GL520_REG_CONF, conf);
 801
 802        gl520_update_device(&(client->dev));
 803
 804        if (data->fan_min[0] == 0)
 805                data->alarm_mask &= ~0x20;
 806        if (data->fan_min[1] == 0)
 807                data->alarm_mask &= ~0x40;
 808
 809        data->beep_mask &= data->alarm_mask;
 810        gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
 811}
 812
 813static int gl520_remove(struct i2c_client *client)
 814{
 815        struct gl520_data *data = i2c_get_clientdata(client);
 816
 817        hwmon_device_unregister(data->hwmon_dev);
 818        sysfs_remove_group(&client->dev.kobj, &gl520_group);
 819        sysfs_remove_group(&client->dev.kobj, &gl520_group_opt);
 820
 821        kfree(data);
 822        return 0;
 823}
 824
 825
 826/* Registers 0x07 to 0x0c are word-sized, others are byte-sized
 827   GL520 uses a high-byte first convention */
 828static int gl520_read_value(struct i2c_client *client, u8 reg)
 829{
 830        if ((reg >= 0x07) && (reg <= 0x0c))
 831                return swab16(i2c_smbus_read_word_data(client, reg));
 832        else
 833                return i2c_smbus_read_byte_data(client, reg);
 834}
 835
 836static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value)
 837{
 838        if ((reg >= 0x07) && (reg <= 0x0c))
 839                return i2c_smbus_write_word_data(client, reg, swab16(value));
 840        else
 841                return i2c_smbus_write_byte_data(client, reg, value);
 842}
 843
 844
 845static struct gl520_data *gl520_update_device(struct device *dev)
 846{
 847        struct i2c_client *client = to_i2c_client(dev);
 848        struct gl520_data *data = i2c_get_clientdata(client);
 849        int val, i;
 850
 851        mutex_lock(&data->update_lock);
 852
 853        if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
 854
 855                dev_dbg(&client->dev, "Starting gl520sm update\n");
 856
 857                data->alarms = gl520_read_value(client, GL520_REG_ALARMS);
 858                data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
 859                data->vid = gl520_read_value(client, GL520_REG_VID_INPUT) & 0x1f;
 860
 861                for (i = 0; i < 4; i++) {
 862                        data->in_input[i] = gl520_read_value(client,
 863                                                        GL520_REG_IN_INPUT[i]);
 864                        val = gl520_read_value(client, GL520_REG_IN_LIMIT[i]);
 865                        data->in_min[i] = val & 0xff;
 866                        data->in_max[i] = (val >> 8) & 0xff;
 867                }
 868
 869                val = gl520_read_value(client, GL520_REG_FAN_INPUT);
 870                data->fan_input[0] = (val >> 8) & 0xff;
 871                data->fan_input[1] = val & 0xff;
 872
 873                val = gl520_read_value(client, GL520_REG_FAN_MIN);
 874                data->fan_min[0] = (val >> 8) & 0xff;
 875                data->fan_min[1] = val & 0xff;
 876
 877                data->temp_input[0] = gl520_read_value(client,
 878                                                GL520_REG_TEMP_INPUT[0]);
 879                data->temp_max[0] = gl520_read_value(client,
 880                                                GL520_REG_TEMP_MAX[0]);
 881                data->temp_max_hyst[0] = gl520_read_value(client,
 882                                                GL520_REG_TEMP_MAX_HYST[0]);
 883
 884                val = gl520_read_value(client, GL520_REG_FAN_DIV);
 885                data->fan_div[0] = (val >> 6) & 0x03;
 886                data->fan_div[1] = (val >> 4) & 0x03;
 887                data->fan_off = (val >> 2) & 0x01;
 888
 889                data->alarms &= data->alarm_mask;
 890
 891                val = gl520_read_value(client, GL520_REG_CONF);
 892                data->beep_enable = !((val >> 2) & 1);
 893
 894                /* Temp1 and Vin4 are the same input */
 895                if (data->two_temps) {
 896                        data->temp_input[1] = gl520_read_value(client,
 897                                                GL520_REG_TEMP_INPUT[1]);
 898                        data->temp_max[1] = gl520_read_value(client,
 899                                                GL520_REG_TEMP_MAX[1]);
 900                        data->temp_max_hyst[1] = gl520_read_value(client,
 901                                                GL520_REG_TEMP_MAX_HYST[1]);
 902                } else {
 903                        data->in_input[4] = gl520_read_value(client,
 904                                                GL520_REG_IN_INPUT[4]);
 905                        data->in_min[4] = gl520_read_value(client,
 906                                                GL520_REG_IN_MIN[4]);
 907                        data->in_max[4] = gl520_read_value(client,
 908                                                GL520_REG_IN_MAX[4]);
 909                }
 910
 911                data->last_updated = jiffies;
 912                data->valid = 1;
 913        }
 914
 915        mutex_unlock(&data->update_lock);
 916
 917        return data;
 918}
 919
 920
 921static int __init sensors_gl520sm_init(void)
 922{
 923        return i2c_add_driver(&gl520_driver);
 924}
 925
 926static void __exit sensors_gl520sm_exit(void)
 927{
 928        i2c_del_driver(&gl520_driver);
 929}
 930
 931
 932MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
 933        "Kyösti Mälkki <kmalkki@cc.hut.fi>, "
 934        "Maarten Deprez <maartendeprez@users.sourceforge.net>");
 935MODULE_DESCRIPTION("GL520SM driver");
 936MODULE_LICENSE("GPL");
 937
 938module_init(sensors_gl520sm_init);
 939module_exit(sensors_gl520sm_exit);
 940
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.