smsc47m1.c (fde0950903ce8cc38a91dd095280decceda2ff82) | smsc47m1.c (2d8672c5a6ba0d3f1d8d3ad61ef67868941364f0) |
---|---|
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> --- 23 unchanged lines hidden (view full) --- 32#include <linux/i2c.h> 33#include <linux/i2c-isa.h> 34#include <linux/i2c-sensor.h> 35#include <linux/hwmon.h> 36#include <linux/err.h> 37#include <linux/init.h> 38#include <asm/io.h> 39 | 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> --- 23 unchanged lines hidden (view full) --- 32#include <linux/i2c.h> 33#include <linux/i2c-isa.h> 34#include <linux/i2c-sensor.h> 35#include <linux/hwmon.h> 36#include <linux/err.h> 37#include <linux/init.h> 38#include <asm/io.h> 39 |
40static unsigned short normal_i2c[] = { I2C_CLIENT_END }; | |
41/* Address is autodetected, there is no default value */ | 40/* Address is autodetected, there is no default value */ |
42static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END }; 43static struct i2c_force_data forces[] = {{NULL}}; | 41static unsigned short address; |
44 | 42 |
45enum chips { any_chip, smsc47m1 }; 46static struct i2c_address_data addr_data = { 47 .normal_i2c = normal_i2c, 48 .normal_isa = normal_isa, 49 .forces = forces, 50}; 51 | |
52/* Super-I/0 registers and commands */ 53 54#define REG 0x2e /* The register to read/write */ 55#define VAL 0x2f /* The value to read/write */ 56 57static inline void 58superio_outb(int reg, int val) 59{ --- 60 unchanged lines hidden (view full) --- 120 u8 fan[2]; /* Register value */ 121 u8 fan_preload[2]; /* Register value */ 122 u8 fan_div[2]; /* Register encoding, shifted right */ 123 u8 alarms; /* Register encoding */ 124 u8 pwm[2]; /* Register value (bit 7 is enable) */ 125}; 126 127 | 43/* Super-I/0 registers and commands */ 44 45#define REG 0x2e /* The register to read/write */ 46#define VAL 0x2f /* The value to read/write */ 47 48static inline void 49superio_outb(int reg, int val) 50{ --- 60 unchanged lines hidden (view full) --- 111 u8 fan[2]; /* Register value */ 112 u8 fan_preload[2]; /* Register value */ 113 u8 fan_div[2]; /* Register encoding, shifted right */ 114 u8 alarms; /* Register encoding */ 115 u8 pwm[2]; /* Register value (bit 7 is enable) */ 116}; 117 118 |
128static int smsc47m1_attach_adapter(struct i2c_adapter *adapter); 129static int smsc47m1_find(int *address); 130static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind); | 119static int smsc47m1_detect(struct i2c_adapter *adapter); |
131static int smsc47m1_detach_client(struct i2c_client *client); 132 133static int smsc47m1_read_value(struct i2c_client *client, u8 reg); 134static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value); 135 136static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 137 int init); 138 139 140static struct i2c_driver smsc47m1_driver = { 141 .owner = THIS_MODULE, 142 .name = "smsc47m1", | 120static int smsc47m1_detach_client(struct i2c_client *client); 121 122static int smsc47m1_read_value(struct i2c_client *client, u8 reg); 123static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value); 124 125static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 126 int init); 127 128 129static struct i2c_driver smsc47m1_driver = { 130 .owner = THIS_MODULE, 131 .name = "smsc47m1", |
143 .id = I2C_DRIVERID_SMSC47M1, 144 .flags = I2C_DF_NOTIFY, 145 .attach_adapter = smsc47m1_attach_adapter, | 132 .attach_adapter = smsc47m1_detect, |
146 .detach_client = smsc47m1_detach_client, 147}; 148 149/* nr is 0 or 1 in the callback functions below */ 150 151static ssize_t get_fan(struct device *dev, char *buf, int nr) 152{ 153 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); --- 199 unchanged lines hidden (view full) --- 353static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ 354 get_pwm##offset##_en, set_pwm##offset##_en); 355 356fan_present(1); 357fan_present(2); 358 359static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); 360 | 133 .detach_client = smsc47m1_detach_client, 134}; 135 136/* nr is 0 or 1 in the callback functions below */ 137 138static ssize_t get_fan(struct device *dev, char *buf, int nr) 139{ 140 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); --- 199 unchanged lines hidden (view full) --- 340static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ 341 get_pwm##offset##_en, set_pwm##offset##_en); 342 343fan_present(1); 344fan_present(2); 345 346static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); 347 |
361static int smsc47m1_attach_adapter(struct i2c_adapter *adapter) | 348static int smsc47m1_find(unsigned short *addr) |
362{ | 349{ |
363 if (!(adapter->class & I2C_CLASS_HWMON)) 364 return 0; 365 return i2c_detect(adapter, &addr_data, smsc47m1_detect); 366} 367 368static int smsc47m1_find(int *address) 369{ | |
370 u8 val; 371 372 superio_enter(); 373 val = superio_inb(SUPERIO_REG_DEVID); 374 375 /* 376 * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id 377 * 0x5F) and LPC47B27x (device id 0x51) have fan control. --- 9 unchanged lines hidden (view full) --- 387 else if (val == 0x60) 388 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M15x/LPC47M192\n"); 389 else { 390 superio_exit(); 391 return -ENODEV; 392 } 393 394 superio_select(); | 350 u8 val; 351 352 superio_enter(); 353 val = superio_inb(SUPERIO_REG_DEVID); 354 355 /* 356 * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id 357 * 0x5F) and LPC47B27x (device id 0x51) have fan control. --- 9 unchanged lines hidden (view full) --- 367 else if (val == 0x60) 368 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M15x/LPC47M192\n"); 369 else { 370 superio_exit(); 371 return -ENODEV; 372 } 373 374 superio_select(); |
395 *address = (superio_inb(SUPERIO_REG_BASE) << 8) 396 | superio_inb(SUPERIO_REG_BASE + 1); | 375 *addr = (superio_inb(SUPERIO_REG_BASE) << 8) 376 | superio_inb(SUPERIO_REG_BASE + 1); |
397 val = superio_inb(SUPERIO_REG_ACT); | 377 val = superio_inb(SUPERIO_REG_ACT); |
398 if (*address == 0 || (val & 0x01) == 0) { | 378 if (*addr == 0 || (val & 0x01) == 0) { |
399 printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n"); 400 superio_exit(); 401 return -ENODEV; 402 } 403 404 superio_exit(); 405 return 0; 406} 407 | 379 printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n"); 380 superio_exit(); 381 return -ENODEV; 382 } 383 384 superio_exit(); 385 return 0; 386} 387 |
408static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) | 388static int smsc47m1_detect(struct i2c_adapter *adapter) |
409{ 410 struct i2c_client *new_client; 411 struct smsc47m1_data *data; 412 int err = 0; 413 int fan1, fan2, pwm1, pwm2; 414 | 389{ 390 struct i2c_client *new_client; 391 struct smsc47m1_data *data; 392 int err = 0; 393 int fan1, fan2, pwm1, pwm2; 394 |
415 if (!i2c_is_isa_adapter(adapter)) { 416 return 0; 417 } 418 | |
419 if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) { 420 dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); 421 return -EBUSY; 422 } 423 424 if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) { 425 err = -ENOMEM; 426 goto error_release; --- 157 unchanged lines hidden (view full) --- 584 } 585 586 up(&data->update_lock); 587 return data; 588} 589 590static int __init sm_smsc47m1_init(void) 591{ | 395 if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) { 396 dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); 397 return -EBUSY; 398 } 399 400 if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) { 401 err = -ENOMEM; 402 goto error_release; --- 157 unchanged lines hidden (view full) --- 560 } 561 562 up(&data->update_lock); 563 return data; 564} 565 566static int __init sm_smsc47m1_init(void) 567{ |
592 if (smsc47m1_find(normal_isa)) { | 568 if (smsc47m1_find(&address)) { |
593 return -ENODEV; 594 } 595 596 return i2c_isa_add_driver(&smsc47m1_driver); 597} 598 599static void __exit sm_smsc47m1_exit(void) 600{ 601 i2c_isa_del_driver(&smsc47m1_driver); 602} 603 604MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>"); 605MODULE_DESCRIPTION("SMSC LPC47M1xx fan sensors driver"); 606MODULE_LICENSE("GPL"); 607 608module_init(sm_smsc47m1_init); 609module_exit(sm_smsc47m1_exit); | 569 return -ENODEV; 570 } 571 572 return i2c_isa_add_driver(&smsc47m1_driver); 573} 574 575static void __exit sm_smsc47m1_exit(void) 576{ 577 i2c_isa_del_driver(&smsc47m1_driver); 578} 579 580MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>"); 581MODULE_DESCRIPTION("SMSC LPC47M1xx fan sensors driver"); 582MODULE_LICENSE("GPL"); 583 584module_init(sm_smsc47m1_init); 585module_exit(sm_smsc47m1_exit); |