smsc47m1.c revision 8d5d45fb14680326f833295f2316a4ec5e357220
1/* 2 smsc47m1.c - Part of lm_sensors, Linux kernel modules 3 for hardware monitoring 4 5 Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x and LPC47M14x 6 Super-I/O chips. 7 8 Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> 9 Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> 10 Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com> 11 and Jean Delvare 12 13 This program is free software; you can redistribute it and/or modify 14 it under the terms of the GNU General Public License as published by 15 the Free Software Foundation; either version 2 of the License, or 16 (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 GNU General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26*/ 27 28#include <linux/module.h> 29#include <linux/slab.h> 30#include <linux/ioport.h> 31#include <linux/jiffies.h> 32#include <linux/i2c.h> 33#include <linux/i2c-sensor.h> 34#include <linux/init.h> 35#include <asm/io.h> 36 37static unsigned short normal_i2c[] = { I2C_CLIENT_END }; 38/* Address is autodetected, there is no default value */ 39static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END }; 40static struct i2c_force_data forces[] = {{NULL}}; 41 42enum chips { any_chip, smsc47m1 }; 43static struct i2c_address_data addr_data = { 44 .normal_i2c = normal_i2c, 45 .normal_isa = normal_isa, 46 .forces = forces, 47}; 48 49/* Super-I/0 registers and commands */ 50 51#define REG 0x2e /* The register to read/write */ 52#define VAL 0x2f /* The value to read/write */ 53 54static inline void 55superio_outb(int reg, int val) 56{ 57 outb(reg, REG); 58 outb(val, VAL); 59} 60 61static inline int 62superio_inb(int reg) 63{ 64 outb(reg, REG); 65 return inb(VAL); 66} 67 68/* logical device for fans is 0x0A */ 69#define superio_select() superio_outb(0x07, 0x0A) 70 71static inline void 72superio_enter(void) 73{ 74 outb(0x55, REG); 75} 76 77static inline void 78superio_exit(void) 79{ 80 outb(0xAA, REG); 81} 82 83#define SUPERIO_REG_ACT 0x30 84#define SUPERIO_REG_BASE 0x60 85#define SUPERIO_REG_DEVID 0x20 86 87/* Logical device registers */ 88 89#define SMSC_EXTENT 0x80 90 91/* nr is 0 or 1 in the macros below */ 92#define SMSC47M1_REG_ALARM 0x04 93#define SMSC47M1_REG_TPIN(nr) (0x34 - (nr)) 94#define SMSC47M1_REG_PPIN(nr) (0x36 - (nr)) 95#define SMSC47M1_REG_PWM(nr) (0x56 + (nr)) 96#define SMSC47M1_REG_FANDIV 0x58 97#define SMSC47M1_REG_FAN(nr) (0x59 + (nr)) 98#define SMSC47M1_REG_FAN_PRELOAD(nr) (0x5B + (nr)) 99 100#define MIN_FROM_REG(reg,div) ((reg)>=192 ? 0 : \ 101 983040/((192-(reg))*(div))) 102#define FAN_FROM_REG(reg,div,preload) ((reg)<=(preload) || (reg)==255 ? 0 : \ 103 983040/(((reg)-(preload))*(div))) 104#define DIV_FROM_REG(reg) (1 << (reg)) 105#define PWM_FROM_REG(reg) (((reg) & 0x7E) << 1) 106#define PWM_EN_FROM_REG(reg) ((~(reg)) & 0x01) 107#define PWM_TO_REG(reg) (((reg) >> 1) & 0x7E) 108 109struct smsc47m1_data { 110 struct i2c_client client; 111 struct semaphore lock; 112 113 struct semaphore update_lock; 114 unsigned long last_updated; /* In jiffies */ 115 116 u8 fan[2]; /* Register value */ 117 u8 fan_preload[2]; /* Register value */ 118 u8 fan_div[2]; /* Register encoding, shifted right */ 119 u8 alarms; /* Register encoding */ 120 u8 pwm[2]; /* Register value (bit 7 is enable) */ 121}; 122 123 124static int smsc47m1_attach_adapter(struct i2c_adapter *adapter); 125static int smsc47m1_find(int *address); 126static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind); 127static int smsc47m1_detach_client(struct i2c_client *client); 128 129static int smsc47m1_read_value(struct i2c_client *client, u8 reg); 130static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value); 131 132static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 133 int init); 134 135 136static struct i2c_driver smsc47m1_driver = { 137 .owner = THIS_MODULE, 138 .name = "smsc47m1", 139 .id = I2C_DRIVERID_SMSC47M1, 140 .flags = I2C_DF_NOTIFY, 141 .attach_adapter = smsc47m1_attach_adapter, 142 .detach_client = smsc47m1_detach_client, 143}; 144 145/* nr is 0 or 1 in the callback functions below */ 146 147static ssize_t get_fan(struct device *dev, char *buf, int nr) 148{ 149 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 150 /* This chip (stupidly) stops monitoring fan speed if PWM is 151 enabled and duty cycle is 0%. This is fine if the monitoring 152 and control concern the same fan, but troublesome if they are 153 not (which could as well happen). */ 154 int rpm = (data->pwm[nr] & 0x7F) == 0x00 ? 0 : 155 FAN_FROM_REG(data->fan[nr], 156 DIV_FROM_REG(data->fan_div[nr]), 157 data->fan_preload[nr]); 158 return sprintf(buf, "%d\n", rpm); 159} 160 161static ssize_t get_fan_min(struct device *dev, char *buf, int nr) 162{ 163 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 164 int rpm = MIN_FROM_REG(data->fan_preload[nr], 165 DIV_FROM_REG(data->fan_div[nr])); 166 return sprintf(buf, "%d\n", rpm); 167} 168 169static ssize_t get_fan_div(struct device *dev, char *buf, int nr) 170{ 171 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 172 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); 173} 174 175static ssize_t get_pwm(struct device *dev, char *buf, int nr) 176{ 177 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 178 return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr])); 179} 180 181static ssize_t get_pwm_en(struct device *dev, char *buf, int nr) 182{ 183 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 184 return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr])); 185} 186 187static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf) 188{ 189 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 190 return sprintf(buf, "%d\n", data->alarms); 191} 192 193static ssize_t set_fan_min(struct device *dev, const char *buf, 194 size_t count, int nr) 195{ 196 struct i2c_client *client = to_i2c_client(dev); 197 struct smsc47m1_data *data = i2c_get_clientdata(client); 198 long rpmdiv, val = simple_strtol(buf, NULL, 10); 199 200 down(&data->update_lock); 201 rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]); 202 203 if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) { 204 up(&data->update_lock); 205 return -EINVAL; 206 } 207 208 data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv); 209 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr), 210 data->fan_preload[nr]); 211 up(&data->update_lock); 212 213 return count; 214} 215 216/* Note: we save and restore the fan minimum here, because its value is 217 determined in part by the fan clock divider. This follows the principle 218 of least suprise; the user doesn't expect the fan minimum to change just 219 because the divider changed. */ 220static ssize_t set_fan_div(struct device *dev, const char *buf, 221 size_t count, int nr) 222{ 223 struct i2c_client *client = to_i2c_client(dev); 224 struct smsc47m1_data *data = i2c_get_clientdata(client); 225 226 long new_div = simple_strtol(buf, NULL, 10), tmp; 227 u8 old_div = DIV_FROM_REG(data->fan_div[nr]); 228 229 if (new_div == old_div) /* No change */ 230 return count; 231 232 down(&data->update_lock); 233 switch (new_div) { 234 case 1: data->fan_div[nr] = 0; break; 235 case 2: data->fan_div[nr] = 1; break; 236 case 4: data->fan_div[nr] = 2; break; 237 case 8: data->fan_div[nr] = 3; break; 238 default: 239 up(&data->update_lock); 240 return -EINVAL; 241 } 242 243 tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F; 244 tmp |= (data->fan_div[0] << 4) | (data->fan_div[1] << 6); 245 smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, tmp); 246 247 /* Preserve fan min */ 248 tmp = 192 - (old_div * (192 - data->fan_preload[nr]) 249 + new_div / 2) / new_div; 250 data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191); 251 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr), 252 data->fan_preload[nr]); 253 up(&data->update_lock); 254 255 return count; 256} 257 258static ssize_t set_pwm(struct device *dev, const char *buf, 259 size_t count, int nr) 260{ 261 struct i2c_client *client = to_i2c_client(dev); 262 struct smsc47m1_data *data = i2c_get_clientdata(client); 263 264 long val = simple_strtol(buf, NULL, 10); 265 266 if (val < 0 || val > 255) 267 return -EINVAL; 268 269 down(&data->update_lock); 270 data->pwm[nr] &= 0x81; /* Preserve additional bits */ 271 data->pwm[nr] |= PWM_TO_REG(val); 272 smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), 273 data->pwm[nr]); 274 up(&data->update_lock); 275 276 return count; 277} 278 279static ssize_t set_pwm_en(struct device *dev, const char *buf, 280 size_t count, int nr) 281{ 282 struct i2c_client *client = to_i2c_client(dev); 283 struct smsc47m1_data *data = i2c_get_clientdata(client); 284 285 long val = simple_strtol(buf, NULL, 10); 286 287 if (val != 0 && val != 1) 288 return -EINVAL; 289 290 down(&data->update_lock); 291 data->pwm[nr] &= 0xFE; /* preserve the other bits */ 292 data->pwm[nr] |= !val; 293 smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), 294 data->pwm[nr]); 295 up(&data->update_lock); 296 297 return count; 298} 299 300#define fan_present(offset) \ 301static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf) \ 302{ \ 303 return get_fan(dev, buf, offset - 1); \ 304} \ 305static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ 306{ \ 307 return get_fan_min(dev, buf, offset - 1); \ 308} \ 309static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr, \ 310 const char *buf, size_t count) \ 311{ \ 312 return set_fan_min(dev, buf, count, offset - 1); \ 313} \ 314static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \ 315{ \ 316 return get_fan_div(dev, buf, offset - 1); \ 317} \ 318static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr, \ 319 const char *buf, size_t count) \ 320{ \ 321 return set_fan_div(dev, buf, count, offset - 1); \ 322} \ 323static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf) \ 324{ \ 325 return get_pwm(dev, buf, offset - 1); \ 326} \ 327static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr, \ 328 const char *buf, size_t count) \ 329{ \ 330 return set_pwm(dev, buf, count, offset - 1); \ 331} \ 332static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf) \ 333{ \ 334 return get_pwm_en(dev, buf, offset - 1); \ 335} \ 336static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr, \ 337 const char *buf, size_t count) \ 338{ \ 339 return set_pwm_en(dev, buf, count, offset - 1); \ 340} \ 341static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset, \ 342 NULL); \ 343static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ 344 get_fan##offset##_min, set_fan##offset##_min); \ 345static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ 346 get_fan##offset##_div, set_fan##offset##_div); \ 347static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ 348 get_pwm##offset, set_pwm##offset); \ 349static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ 350 get_pwm##offset##_en, set_pwm##offset##_en); 351 352fan_present(1); 353fan_present(2); 354 355static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); 356 357static int smsc47m1_attach_adapter(struct i2c_adapter *adapter) 358{ 359 if (!(adapter->class & I2C_CLASS_HWMON)) 360 return 0; 361 return i2c_detect(adapter, &addr_data, smsc47m1_detect); 362} 363 364static int smsc47m1_find(int *address) 365{ 366 u8 val; 367 368 superio_enter(); 369 val = superio_inb(SUPERIO_REG_DEVID); 370 371 /* 372 * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id 373 * 0x5F) and LPC47B27x (device id 0x51) have fan control. 374 * The LPC47M15x and LPC47M192 chips "with hardware monitoring block" 375 * can do much more besides (device id 0x60). 376 */ 377 if (val == 0x51) 378 printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n"); 379 else if (val == 0x59) 380 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M10x/LPC47M13x\n"); 381 else if (val == 0x5F) 382 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n"); 383 else if (val == 0x60) 384 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M15x/LPC47M192\n"); 385 else { 386 superio_exit(); 387 return -ENODEV; 388 } 389 390 superio_select(); 391 *address = (superio_inb(SUPERIO_REG_BASE) << 8) 392 | superio_inb(SUPERIO_REG_BASE + 1); 393 val = superio_inb(SUPERIO_REG_ACT); 394 if (*address == 0 || (val & 0x01) == 0) { 395 printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n"); 396 superio_exit(); 397 return -ENODEV; 398 } 399 400 superio_exit(); 401 return 0; 402} 403 404static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) 405{ 406 struct i2c_client *new_client; 407 struct smsc47m1_data *data; 408 int err = 0; 409 int fan1, fan2, pwm1, pwm2; 410 411 if (!i2c_is_isa_adapter(adapter)) { 412 return 0; 413 } 414 415 if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) { 416 dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); 417 return -EBUSY; 418 } 419 420 if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) { 421 err = -ENOMEM; 422 goto error_release; 423 } 424 memset(data, 0x00, sizeof(struct smsc47m1_data)); 425 426 new_client = &data->client; 427 i2c_set_clientdata(new_client, data); 428 new_client->addr = address; 429 init_MUTEX(&data->lock); 430 new_client->adapter = adapter; 431 new_client->driver = &smsc47m1_driver; 432 new_client->flags = 0; 433 434 strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE); 435 init_MUTEX(&data->update_lock); 436 437 /* If no function is properly configured, there's no point in 438 actually registering the chip. */ 439 fan1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(0)) & 0x05) 440 == 0x05; 441 fan2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(1)) & 0x05) 442 == 0x05; 443 pwm1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05) 444 == 0x04; 445 pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05) 446 == 0x04; 447 if (!(fan1 || fan2 || pwm1 || pwm2)) { 448 dev_warn(&new_client->dev, "Device is not configured, will not use\n"); 449 err = -ENODEV; 450 goto error_free; 451 } 452 453 if ((err = i2c_attach_client(new_client))) 454 goto error_free; 455 456 /* Some values (fan min, clock dividers, pwm registers) may be 457 needed before any update is triggered, so we better read them 458 at least once here. We don't usually do it that way, but in 459 this particular case, manually reading 5 registers out of 8 460 doesn't make much sense and we're better using the existing 461 function. */ 462 smsc47m1_update_device(&new_client->dev, 1); 463 464 if (fan1) { 465 device_create_file(&new_client->dev, &dev_attr_fan1_input); 466 device_create_file(&new_client->dev, &dev_attr_fan1_min); 467 device_create_file(&new_client->dev, &dev_attr_fan1_div); 468 } else 469 dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, " 470 "skipping\n"); 471 472 if (fan2) { 473 device_create_file(&new_client->dev, &dev_attr_fan2_input); 474 device_create_file(&new_client->dev, &dev_attr_fan2_min); 475 device_create_file(&new_client->dev, &dev_attr_fan2_div); 476 } else 477 dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, " 478 "skipping\n"); 479 480 if (pwm1) { 481 device_create_file(&new_client->dev, &dev_attr_pwm1); 482 device_create_file(&new_client->dev, &dev_attr_pwm1_enable); 483 } else 484 dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, " 485 "skipping\n"); 486 if (pwm2) { 487 device_create_file(&new_client->dev, &dev_attr_pwm2); 488 device_create_file(&new_client->dev, &dev_attr_pwm2_enable); 489 } else 490 dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, " 491 "skipping\n"); 492 493 device_create_file(&new_client->dev, &dev_attr_alarms); 494 495 return 0; 496 497error_free: 498 kfree(new_client); 499error_release: 500 release_region(address, SMSC_EXTENT); 501 return err; 502} 503 504static int smsc47m1_detach_client(struct i2c_client *client) 505{ 506 int err; 507 508 if ((err = i2c_detach_client(client))) { 509 dev_err(&client->dev, "Client deregistration failed, " 510 "client not detached.\n"); 511 return err; 512 } 513 514 release_region(client->addr, SMSC_EXTENT); 515 kfree(i2c_get_clientdata(client)); 516 517 return 0; 518} 519 520static int smsc47m1_read_value(struct i2c_client *client, u8 reg) 521{ 522 int res; 523 524 down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); 525 res = inb_p(client->addr + reg); 526 up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); 527 return res; 528} 529 530static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value) 531{ 532 down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); 533 outb_p(value, client->addr + reg); 534 up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); 535} 536 537static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 538 int init) 539{ 540 struct i2c_client *client = to_i2c_client(dev); 541 struct smsc47m1_data *data = i2c_get_clientdata(client); 542 543 down(&data->update_lock); 544 545 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) { 546 int i; 547 548 for (i = 0; i < 2; i++) { 549 data->fan[i] = smsc47m1_read_value(client, 550 SMSC47M1_REG_FAN(i)); 551 data->fan_preload[i] = smsc47m1_read_value(client, 552 SMSC47M1_REG_FAN_PRELOAD(i)); 553 data->pwm[i] = smsc47m1_read_value(client, 554 SMSC47M1_REG_PWM(i)); 555 } 556 557 i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV); 558 data->fan_div[0] = (i >> 4) & 0x03; 559 data->fan_div[1] = i >> 6; 560 561 data->alarms = smsc47m1_read_value(client, 562 SMSC47M1_REG_ALARM) >> 6; 563 /* Clear alarms if needed */ 564 if (data->alarms) 565 smsc47m1_write_value(client, SMSC47M1_REG_ALARM, 0xC0); 566 567 data->last_updated = jiffies; 568 } 569 570 up(&data->update_lock); 571 return data; 572} 573 574static int __init sm_smsc47m1_init(void) 575{ 576 if (smsc47m1_find(normal_isa)) { 577 return -ENODEV; 578 } 579 580 return i2c_add_driver(&smsc47m1_driver); 581} 582 583static void __exit sm_smsc47m1_exit(void) 584{ 585 i2c_del_driver(&smsc47m1_driver); 586} 587 588MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>"); 589MODULE_DESCRIPTION("SMSC LPC47M1xx fan sensors driver"); 590MODULE_LICENSE("GPL"); 591 592module_init(sm_smsc47m1_init); 593module_exit(sm_smsc47m1_exit); 594