Changeset 115

Show
Ignore:
Timestamp:
12/25/98 20:30:44 (14 years ago)
Author:
frodo
Message:

Completed the LM80 driver. Untested.

Location:
lm-sensors/trunk
Files:
10 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/kernel/Module.mk

    r92 r115  
    2727              $(MODULE_DIR)/i2c-proc.o $(MODULE_DIR)/lm75.o \ 
    2828              $(MODULE_DIR)/i2c-proc.o $(MODULE_DIR)/gl518sm.o \ 
    29               $(MODULE_DIR)/eeprom.o $(MODULE_DIR)/w83781d.o  
     29              $(MODULE_DIR)/eeprom.o $(MODULE_DIR)/w83781d.o \ 
     30              $(MODULE_DIR)/lm80.o 
    3031 
    3132SRCHEADERFILES := $(MODULE_DIR)/sensors.h $(MODULE_DIR)/isa.h \ 
  • lm-sensors/trunk/kernel/chips/gl518sm.c

    r112 r115  
    6666#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) 
    6767#define DIV_FROM_REG(val) (1 << (val)) 
     68 
     69#define ALARMS_FROM_REG(val) val 
    6870 
    6971#define BEEP_ENABLE_TO_REG(val) ((val)?0:1) 
     
    566568  else if (operation == SENSORS_PROC_REAL_READ) { 
    567569    gl518_update_client(client); 
    568     results[0] = data->alarms; 
     570    results[0] = ALARMS_FROM_REG(data->alarms); 
    569571    *nrels_mag = 1; 
    570572  } 
  • lm-sensors/trunk/kernel/chips/lm78.c

    r114 r115  
    1  
    21/* 
    32    lm78.c - Part of lm_sensors, Linux kernel modules for hardware 
  • lm-sensors/trunk/kernel/chips/lm80.c

    r113 r115  
    1  
    21/* 
    32    lm80.c - Part of lm_sensors, Linux kernel modules for hardware 
     
    4342#define LM80_REG_IN(nr) (0x20 + (nr)) 
    4443 
    45 #define LM80_REG_FAN_MIN(nr) (0x3b + (nr)) 
    46 #define LM80_REG_FAN(nr) (0x27 + (nr)) 
     44#define LM80_REG_FAN1_MIN 0x3c 
     45#define LM80_REG_FAN2_MIN 0x3d 
     46#define LM80_REG_FAN1 0x28 
     47#define LM80_REG_FAN2 0x29 
    4748 
    4849#define LM80_REG_TEMP 0x27 
    49 #define LM80_REG_TEMP_OVER 0x39 
    50 #define LM80_REG_TEMP_HYST 0x3a 
    51  
    52 #define LM80_REG_ALARM1 0x41 
    53 #define LM80_REG_ALARM2 0x42 
    54  
    55 #define LM80_REG_VID_FANDIV 0x47 
    56  
    57 #define LM80_REG_CONFIG 0x40 
    58 #define LM80_REG_CHIPID 0x49 
     50#define LM80_REG_TEMP_HOT_MAX 0x38 
     51#define LM80_REG_TEMP_HOT_HYST 0x39 
     52#define LM80_REG_TEMP_OS_MAX 0x3a 
     53#define LM80_REG_TEMP_OS_HYST 0x3b 
     54 
     55#define LM80_REG_CONFIG 0x00 
     56#define LM80_REG_ALARM1 0x01 
     57#define LM80_REG_ALARM2 0x02 
     58#define LM80_REG_MASK1 0x03 
     59#define LM80_REG_MASK2 0x04 
     60#define LM80_REG_FANDIV 0x05 
     61#define LM80_REG_RES 0x06 
    5962 
    6063 
    6164/* Conversions. Rounding is only done on the TO_REG variants. */ 
    62 #define IN_TO_REG(val,nr) (((((val) * 100000 / lm80_in_conv[nr]) + 8) / 16) \ 
    63                            & 0xff) 
    64 #define IN_FROM_REG(val,nr) (((val) *  16 * lm80_in_conv[nr]) / 100000) 
    65  
    66 #define FAN_TO_REG(val) ((val)==0?255:((1350000+(val))/((val)*2)) & 0xff) 
    67 #define FAN_FROM_REG(val) ((val)==0?-1:(val)==255?0:1350000/((val)*2)) 
    68  
    69 #define TEMP_TO_REG(val) (((val)<0?(((val)-5)/10)&0xff:((val)+5)/10) & 0xff) 
    70 #define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) 
    71  
    72 #define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ 
    73                            (val)>=0x06?0:205-(val)*5) 
    74 #define ALARMS_FROM_REG(val) (val) 
     65#define IN_TO_REG(val,nr) ((val) & 0xff) 
     66#define IN_FROM_REG(val,nr) (val) 
     67 
     68#define FAN_TO_REG(val,div) ((val)==0?255:\ 
     69                             ((1350000+(val)*(div))/((val)*(div)*2)) & 0xff) 
     70#define FAN_FROM_REG(val,div) ((val)==0?-1:\ 
     71                               (val)==255?0:1350000/((div)*(val)*2)) 
     72 
     73#define TEMP_FROM_REG(val) lm80_temp_from_reg(val) 
     74 
     75#define TEMP_LIMIT_TO_REG(val) (((val)<0?(((val)-50)/100)&0xff:\ 
     76                                           ((val)+50)/100) & 0xff) 
     77#define TEMP_LIMIT_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*100) 
     78 
     79#define ALARMS_FROM_REG(val) (val)  
    7580 
    7681#define DIV_FROM_REG(val) (1 << (val)) 
     
    7883 
    7984/* Initial limits */ 
    80 #define LM80_INIT_IN_0 (vid==350?280:vid) 
    81 #define LM80_INIT_IN_1 (vid==350?280:vid) 
    82 #define LM80_INIT_IN_2 330 
    83 #define LM80_INIT_IN_3 500 
    84 #define LM80_INIT_IN_4 1200 
    85 #define LM80_INIT_IN_5 -1200 
    86 #define LM80_INIT_IN_6 -500 
     85#define LM80_INIT_IN_0 190 
     86#define LM80_INIT_IN_1 190 
     87#define LM80_INIT_IN_2 190 
     88#define LM80_INIT_IN_3 190 
     89#define LM80_INIT_IN_4 190 
     90#define LM80_INIT_IN_5 190 
     91#define LM80_INIT_IN_6 190 
    8792 
    8893#define LM80_INIT_IN_PERCENTAGE 10 
     
    119124#define LM80_INIT_FAN_MIN_1 3000 
    120125#define LM80_INIT_FAN_MIN_2 3000 
    121 #define LM80_INIT_FAN_MIN_3 3000 
    122  
    123 #define LM80_INIT_TEMP_OVER 600 
    124 #define LM80_INIT_TEMP_HYST 500 
     126 
     127#define LM80_INIT_TEMP_OS_MAX 600 
     128#define LM80_INIT_TEMP_OS_HYST 500 
     129#define LM80_INIT_TEMP_HOT_MAX 700 
     130#define LM80_INIT_TEMP_HOT_HYST 600 
    125131 
    126132#ifdef MODULE 
     
    128134extern int cleanup_module(void); 
    129135#endif /* MODULE */ 
    130  
    131 /* This module may seem overly long and complicated. In fact, it is not so 
    132    bad. Quite a lot of bookkeeping is done. A real driver can often cut 
    133    some corners. */ 
    134136 
    135137/* For each registered LM80, we need to keep some data in memory. That 
     
    138140   allocated. */ 
    139141struct lm80_data { 
    140          struct semaphore lock; 
    141142         int sysctl_id; 
    142143 
     
    148149         u8 in_max[7];               /* Register value */ 
    149150         u8 in_min[7];               /* Register value */ 
    150          u8 fan[3];                  /* Register value */ 
    151          u8 fan_min[3];              /* Register value */ 
    152          u8 temp;                    /* Register value */ 
    153          u8 temp_over;               /* Register value */ 
    154          u8 temp_hyst;               /* Register value */ 
     151         u8 fan[2];                  /* Register value */ 
     152         u8 fan_min[2];              /* Register value */ 
    155153         u8 fan_div[2];              /* Register encoding, shifted right */ 
    156          u8 vid;                     /* Register encoding, combined */ 
     154         u16 temp;                   /* Register values, shifted right */ 
     155         u8 temp_hot_max;            /* Register value */ 
     156         u8 temp_hot_hyst;           /* Register value */ 
     157         u8 temp_os_max;             /* Register value */ 
     158         u8 temp_os_hyst;            /* Register value */ 
    157159         u16 alarms;                 /* Register encoding, combined */ 
    158160}; 
     
    163165 
    164166static int lm80_attach_adapter(struct i2c_adapter *adapter); 
    165 static int lm80_detect_smbus(struct i2c_adapter *adapter); 
    166167static int lm80_detach_client(struct i2c_client *client); 
    167 static int lm80_detach_smbus(struct i2c_client *client); 
    168168static int lm80_new_client(struct i2c_adapter *adapter, 
    169169                           struct i2c_client *new_client); 
     
    174174static void lm80_dec_use (struct i2c_client *client); 
    175175 
     176static long lm80_temp_from_reg(u16 regs); 
     177 
    176178static int lm80_read_value(struct i2c_client *client, u8 register); 
    177179static int lm80_write_value(struct i2c_client *client, u8 register, u8 value); 
     
    186188static void lm80_temp(struct i2c_client *client, int operation, int ctl_name, 
    187189                      int *nrels_mag, long *results); 
    188 static void lm80_vid(struct i2c_client *client, int operation, int ctl_name, 
    189                      int *nrels_mag, long *results); 
    190190static void lm80_alarms(struct i2c_client *client, int operation, int ctl_name, 
    191191                        int *nrels_mag, long *results); 
     
    240240  { LM80_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &sensors_proc_real, 
    241241    &sensors_sysctl_real, NULL, &lm80_fan }, 
    242   { LM80_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &sensors_proc_real, 
    243     &sensors_sysctl_real, NULL, &lm80_fan }, 
    244242  { LM80_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &sensors_proc_real, 
    245243    &sensors_sysctl_real, NULL, &lm80_temp }, 
    246   { LM80_SYSCTL_VID, "vid", NULL, 0, 0644, NULL, &sensors_proc_real, 
    247     &sensors_sysctl_real, NULL, &lm80_vid }, 
    248244  { LM80_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &sensors_proc_real, 
    249245    &sensors_sysctl_real, NULL, &lm80_fan_div }, 
     
    254250 
    255251 
    256 /* This function is called when: 
    257      * lm80_driver is inserted (when this module is loaded), for each 
    258        available adapter 
    259      * when a new adapter is inserted (and lm80_driver is still present) */ 
    260252int lm80_attach_adapter(struct i2c_adapter *adapter) 
    261 { 
    262     return lm80_detect_smbus(adapter); 
    263 } 
    264  
    265 /* This function is called whenever a client should be removed: 
    266     * lm80_driver is removed (when this module is unloaded) 
    267     * when an adapter is removed which has a lm80 client (and lm80_driver 
    268       is still present). */ 
    269 int lm80_detach_client(struct i2c_client *client) 
    270 { 
    271     return lm80_detach_smbus(client); 
    272 } 
    273  
    274 int lm80_detect_smbus(struct i2c_adapter *adapter) 
    275253{ 
    276254  int address,err; 
     
    290268    /* Real detection code goes here */ 
    291269 
    292     err = smbus_read_byte_data(adapter,address,LM80_REG_CHIPID) & 0xfe; 
    293  
    294270    printk("lm80.o: LM80 detected\n"); 
    295271    type_name = "lm80"; 
     
    298274 
    299275    /* Allocate space for a new client structure. To counter memory 
    300        ragmentation somewhat, we only do one kmalloc. */ 
     276       fragmentation somewhat, we only do one kmalloc. */ 
    301277    if (! (new_client = kmalloc(sizeof(struct i2c_client) +  
    302278                                sizeof(struct lm80_data), 
     
    340316} 
    341317 
    342 int lm80_detach_smbus(struct i2c_client *client) 
     318int lm80_detach_client(struct i2c_client *client) 
    343319{ 
    344320  int err,i; 
     
    386362  data = new_client->data; 
    387363  data->valid = 0; 
    388   data->lock = MUTEX; 
    389364  data->update_lock = MUTEX; 
    390365  return 0; 
     
    406381} 
    407382 
    408 /* Nothing here yet */ 
    409383void lm80_inc_use (struct i2c_client *client) 
    410384{ 
     
    414388} 
    415389 
    416 /* Nothing here yet */ 
    417390void lm80_dec_use (struct i2c_client *client) 
    418391{ 
     
    423396  
    424397 
    425 /* The SMBus locks itself, but ISA access must be locked explicitely!  
    426    We ignore the LM80 BUSY flag at this moment - it could lead to deadlocks, 
    427    would slow down the LM80 access and should not be necessary.  
    428    There are some ugly typecasts here, but the good new is - they should 
    429    nowhere else be necessary! */ 
     398long lm80_temp_from_reg(u16 temp) 
     399{ 
     400  long res; 
     401  res = ((temp & 0xff00) >> 8) * 10000 + ((temp & 0x10) >> 4) * 5000 + 
     402        ((temp & 0x20) >> 5) * 2500 + ((temp & 0x40) >> 6) * 1250 + 
     403        ((temp & 0x80) >> 7) * 625; 
     404  temp /= 100; 
     405  if (temp >= 0x80 * 100) 
     406    temp = - (0x100 * 100 - temp); 
     407  return temp; 
     408} 
     409 
    430410int lm80_read_value(struct i2c_client *client, u8 reg) 
    431411{ 
    432   int res; 
    433   if (i2c_is_isa_client(client)) { 
    434     down((struct semaphore *) (client->data)); 
    435     outb_p(reg,(((struct isa_client *) client)->isa_addr) +  
    436                LM80_ADDR_REG_OFFSET); 
    437     res = inb_p((((struct isa_client *) client)->isa_addr) +  
    438                 LM80_DATA_REG_OFFSET); 
    439     up((struct semaphore *) (client->data)); 
    440     return res; 
    441   } else 
    442     return smbus_read_byte_data(client->adapter,client->addr, reg); 
    443 } 
    444  
    445 /* The SMBus locks itself, but ISA access muse be locked explicitely!  
    446    We ignore the LM80 BUSY flag at this moment - it could lead to deadlocks, 
    447    would slow down the LM80 access and should not be necessary.  
    448    There are some ugly typecasts here, but the good new is - they should 
    449    nowhere else be necessary! */ 
     412  return smbus_read_byte_data(client->adapter,client->addr, reg); 
     413} 
     414 
    450415int lm80_write_value(struct i2c_client *client, u8 reg, u8 value) 
    451416{ 
    452   if (i2c_is_isa_client(client)) { 
    453     down((struct semaphore *) (client->data)); 
    454     outb_p(reg,((struct isa_client *) client)->isa_addr + LM80_ADDR_REG_OFFSET); 
    455     outb_p(value,((struct isa_client *) client)->isa_addr + LM80_DATA_REG_OFFSET); 
    456     up((struct semaphore *) (client->data)); 
    457     return 0; 
    458   } else 
    459     return smbus_write_byte_data(client->adapter, client->addr, reg,value); 
     417  return smbus_write_byte_data(client->adapter, client->addr, reg,value); 
    460418} 
    461419 
     
    463421void lm80_init_client(struct i2c_client *client) 
    464422{ 
    465   int vid; 
    466  
    467423  /* Reset all except Watchdog values and last conversion values 
    468      This sets fan-divs to 2, among others */ 
     424     This sets fan-divs to 2, among others. This makes most other 
     425     initializations unnecessary */ 
    469426  lm80_write_value(client,LM80_REG_CONFIG,0x80); 
    470  
    471   vid = lm80_read_value(client,LM80_REG_VID_FANDIV) & 0x0f; 
    472   vid |= (lm80_read_value(client,LM80_REG_CHIPID) & 0x01) >> 4; 
    473   vid = VID_FROM_REG(vid); 
     427  /* Set 11-bit temperature resolution */ 
     428  lm80_write_value(client,LM80_REG_RES,0x08); 
    474429 
    475430  lm80_write_value(client,LM80_REG_IN_MIN(0),IN_TO_REG(LM80_INIT_IN_MIN_0,0)); 
     
    487442  lm80_write_value(client,LM80_REG_IN_MIN(6),IN_TO_REG(LM80_INIT_IN_MIN_6,6)); 
    488443  lm80_write_value(client,LM80_REG_IN_MAX(6),IN_TO_REG(LM80_INIT_IN_MAX_6,6)); 
    489   lm80_write_value(client,LM80_REG_FAN_MIN(1),FAN_TO_REG(LM80_INIT_FAN_MIN_1)); 
    490   lm80_write_value(client,LM80_REG_FAN_MIN(2),FAN_TO_REG(LM80_INIT_FAN_MIN_2)); 
    491   lm80_write_value(client,LM80_REG_FAN_MIN(3),FAN_TO_REG(LM80_INIT_FAN_MIN_3)); 
    492   lm80_write_value(client,LM80_REG_TEMP_OVER,TEMP_TO_REG(LM80_INIT_TEMP_OVER)); 
    493   lm80_write_value(client,LM80_REG_TEMP_HYST,TEMP_TO_REG(LM80_INIT_TEMP_HYST)); 
     444  lm80_write_value(client,LM80_REG_FAN1_MIN,FAN_TO_REG(LM80_INIT_FAN_MIN_1,2)); 
     445  lm80_write_value(client,LM80_REG_FAN2_MIN,FAN_TO_REG(LM80_INIT_FAN_MIN_2,2)); 
     446  lm80_write_value(client,LM80_REG_TEMP_HOT_MAX, 
     447                   TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_MAX)); 
     448  lm80_write_value(client,LM80_REG_TEMP_HOT_HYST, 
     449                   TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_HYST)); 
     450  lm80_write_value(client,LM80_REG_TEMP_OS_MAX, 
     451                   TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_MAX)); 
     452  lm80_write_value(client,LM80_REG_TEMP_OS_HYST, 
     453                   TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_HYST)); 
    494454 
    495455  /* Start monitoring */ 
    496   lm80_write_value(client,LM80_REG_CONFIG, 
    497                    (lm80_read_value(client,LM80_REG_CONFIG) & 0xf7) | 0x01); 
    498    
     456  lm80_write_value(client,LM80_REG_CONFIG,0x01); 
    499457} 
    500458 
     
    506464  down(&data->update_lock); 
    507465 
    508   if ((jiffies - data->last_updated > HZ+HZ/2 ) || 
     466  if ((jiffies - data->last_updated > 2*HZ ) || 
    509467      (jiffies < data->last_updated) || ! data->valid) { 
    510468 
     
    517475      data->in_max[i] = lm80_read_value(client,LM80_REG_IN_MAX(i)); 
    518476    } 
    519     for (i = 1; i <= 3; i++) { 
    520       data->fan[i-1] = lm80_read_value(client,LM80_REG_FAN(i)); 
    521       data->fan_min[i-1] = lm80_read_value(client,LM80_REG_FAN_MIN(i)); 
    522     } 
    523     data->temp = lm80_read_value(client,LM80_REG_TEMP); 
    524     data->temp_over = lm80_read_value(client,LM80_REG_TEMP_OVER); 
    525     data->temp_hyst = lm80_read_value(client,LM80_REG_TEMP_HYST); 
    526     i = lm80_read_value(client,LM80_REG_VID_FANDIV); 
    527     data->vid = i & 0x0f; 
    528     data->vid |= (lm80_read_value(client,LM80_REG_CHIPID) & 0x01) >> 4; 
    529     data->fan_div[0] = (i >> 4) & 0x03; 
    530     data->fan_div[1] = i >> 6; 
     477    data->fan[0] = lm80_read_value(client,LM80_REG_FAN1); 
     478    data->fan_min[0] = lm80_read_value(client,LM80_REG_FAN1_MIN); 
     479    data->fan[1] = lm80_read_value(client,LM80_REG_FAN2); 
     480    data->fan_min[1] = lm80_read_value(client,LM80_REG_FAN2_MIN); 
     481    
     482    data->temp = (lm80_read_value(client,LM80_REG_TEMP) << 8) | 
     483                 (lm80_read_value(client,LM80_REG_RES) & 0xf0); 
     484    data->temp_os_max = lm80_read_value(client,LM80_REG_TEMP_OS_MAX); 
     485    data->temp_os_hyst = lm80_read_value(client,LM80_REG_TEMP_OS_HYST); 
     486    data->temp_hot_max = lm80_read_value(client,LM80_REG_TEMP_HOT_MAX); 
     487    data->temp_hot_hyst = lm80_read_value(client,LM80_REG_TEMP_HOT_HYST); 
     488 
     489    i = lm80_read_value(client,LM80_REG_FANDIV); 
     490    data->fan_div[0] = (i >> 2) & 0x03; 
     491    data->fan_div[1] = (i >> 4) & 0x03; 
    531492    data->alarms = lm80_read_value(client,LM80_REG_ALARM1) + 
    532                    (lm80_read_value(client,LM80_REG_ALARM2) >> 8); 
     493                   (lm80_read_value(client,LM80_REG_ALARM2) << 8); 
    533494    data->last_updated = jiffies; 
    534495    data->valid = 1; 
     
    588549  else if (operation == SENSORS_PROC_REAL_READ) { 
    589550    lm80_update_client(client); 
    590     results[0] = FAN_FROM_REG(data->fan_min[nr-1]); 
    591     results[1] = FAN_FROM_REG(data->fan[nr-1]); 
     551    results[0] = FAN_FROM_REG(data->fan_min[nr-1],data->fan_div[nr-1]); 
     552    results[1] = FAN_FROM_REG(data->fan[nr-1],data->fan_div[nr-1]); 
    592553    *nrels_mag = 2; 
    593554  } else if (operation == SENSORS_PROC_REAL_WRITE) { 
    594555    if (*nrels_mag >= 1) { 
    595       data->fan_min[nr-1] = FAN_TO_REG(results[0]); 
    596       lm80_write_value(client,LM80_REG_FAN_MIN(nr),data->fan_min[nr-1]); 
     556      data->fan_min[nr-1] = FAN_TO_REG(results[0],data->fan_div[nr-1]); 
     557      lm80_write_value(client,nr==1?LM80_REG_FAN1_MIN:LM80_REG_FAN2_MIN, 
     558                       data->fan_min[nr-1]); 
    597559    } 
    598560  } 
     
    608570  else if (operation == SENSORS_PROC_REAL_READ) { 
    609571    lm80_update_client(client); 
    610     results[0] = TEMP_FROM_REG(data->temp_over); 
    611     results[1] = TEMP_FROM_REG(data->temp_hyst); 
    612     results[2] = TEMP_FROM_REG(data->temp); 
    613     *nrels_mag = 3; 
     572    results[0] = TEMP_LIMIT_FROM_REG(data->temp_hot_max); 
     573    results[1] = TEMP_LIMIT_FROM_REG(data->temp_hot_hyst); 
     574    results[2] = TEMP_LIMIT_FROM_REG(data->temp_os_max); 
     575    results[3] = TEMP_LIMIT_FROM_REG(data->temp_os_hyst); 
     576    results[4] = TEMP_FROM_REG(data->temp); 
     577    *nrels_mag = 5; 
    614578  } else if (operation == SENSORS_PROC_REAL_WRITE) { 
    615579    if (*nrels_mag >= 1) { 
    616       data->temp_over = TEMP_TO_REG(results[0]); 
    617       lm80_write_value(client,LM80_REG_TEMP_OVER,data->temp_over); 
     580      data->temp_hot_max = TEMP_LIMIT_TO_REG(results[0]); 
     581      lm80_write_value(client,LM80_REG_TEMP_HOT_MAX,data->temp_hot_max); 
    618582    } 
    619583    if (*nrels_mag >= 2) { 
    620       data->temp_hyst = TEMP_TO_REG(results[1]); 
    621       lm80_write_value(client,LM80_REG_TEMP_HYST,data->temp_hyst); 
    622     } 
    623   } 
    624 } 
    625  
    626 void lm80_vid(struct i2c_client *client, int operation, int ctl_name, 
    627               int *nrels_mag, long *results) 
    628 { 
    629   struct lm80_data *data = client->data; 
    630   if (operation == SENSORS_PROC_REAL_INFO) 
    631     *nrels_mag = 2; 
    632   else if (operation == SENSORS_PROC_REAL_READ) { 
    633     lm80_update_client(client); 
    634     results[0] = VID_FROM_REG(data->vid); 
    635     *nrels_mag = 1; 
     584      data->temp_hot_hyst = TEMP_LIMIT_TO_REG(results[1]); 
     585      lm80_write_value(client,LM80_REG_TEMP_HOT_HYST,data->temp_hot_hyst); 
     586    } 
     587    if (*nrels_mag >= 3) { 
     588      data->temp_os_max = TEMP_LIMIT_TO_REG(results[2]); 
     589      lm80_write_value(client,LM80_REG_TEMP_OS_MAX,data->temp_os_max); 
     590    } 
     591    if (*nrels_mag >= 4) { 
     592      data->temp_os_hyst = TEMP_LIMIT_TO_REG(results[3]); 
     593      lm80_write_value(client,LM80_REG_TEMP_OS_HYST,data->temp_os_hyst); 
     594    } 
    636595  } 
    637596} 
     
    665624    *nrels_mag = 3; 
    666625  } else if (operation == SENSORS_PROC_REAL_WRITE) { 
    667     old = lm80_read_value(client,LM80_REG_VID_FANDIV); 
     626    old = lm80_read_value(client,LM80_REG_FANDIV); 
    668627    if (*nrels_mag >= 2) { 
    669628      data->fan_div[1] = DIV_TO_REG(results[1]); 
    670       old = (old & 0x3f) | (data->fan_div[1] << 6); 
     629      old = (old & 0xcf) | (data->fan_div[1] << 4); 
    671630    } 
    672631    if (*nrels_mag >= 1) { 
    673632      data->fan_div[0] = DIV_TO_REG(results[0]); 
    674       old = (old & 0xcf) | (data->fan_div[0] << 4); 
    675       lm80_write_value(client,LM80_REG_VID_FANDIV,old); 
     633      old = (old & 0xf3) | (data->fan_div[0] << 2); 
     634      lm80_write_value(client,LM80_REG_FANDIV,old); 
    676635    } 
    677636  } 
  • lm-sensors/trunk/kernel/include/sensors.h

    r112 r115  
    8888#define I2C_DRIVERID_EEPROM 1005 
    8989#define I2C_DRIVERID_W83781D 1006 
     90#define I2C_DRIVERID_LM80 1007 
    9091 
    9192/* Sysctl IDs */ 
     
    199200#define EEPROM_SYSCTL8 1007 
    200201 
     202#define LM80_SYSCTL_IN0 1000  /* Volts * 100 */ 
     203#define LM80_SYSCTL_IN1 1001 
     204#define LM80_SYSCTL_IN2 1002 
     205#define LM80_SYSCTL_IN3 1003 
     206#define LM80_SYSCTL_IN4 1004 
     207#define LM80_SYSCTL_IN5 1005 
     208#define LM80_SYSCTL_IN6 1006 
     209#define LM80_SYSCTL_FAN1 1101 /* Rotations/min */ 
     210#define LM80_SYSCTL_FAN2 1102 
     211#define LM80_SYSCTL_TEMP 1250 /* Degrees Celcius * 100 */ 
     212#define LM80_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ 
     213#define LM80_SYSCTL_ALARMS 2001 /* bitvector */ 
     214 
     215#define LM80_ALARM_IN0 0x0001 
     216#define LM80_ALARM_IN1 0x0002 
     217#define LM80_ALARM_IN2 0x0004 
     218#define LM80_ALARM_IN3 0x0008 
     219#define LM80_ALARM_IN4 0x0010 
     220#define LM80_ALARM_IN5 0x0020 
     221#define LM80_ALARM_IN6 0x0040 
     222#define LM80_ALARM_FAN1 0x0400 
     223#define LM80_ALARM_FAN2 0x0800 
     224#define LM80_ALARM_TEMP_HOT 0x0100 
     225#define LM80_ALARM_TEMP_OS 0x2000 
     226#define LM80_ALARM_CHAS 0x1000 
     227#define LM80_ALARM_BTI 0x0200 
     228#define LM80_ALARM_INT_IN 0x0080 
    201229#endif /* def SENSORS_SENSORS_H */ 
  • lm-sensors/trunk/src/Module.mk

    r92 r115  
    2727              $(MODULE_DIR)/i2c-proc.o $(MODULE_DIR)/lm75.o \ 
    2828              $(MODULE_DIR)/i2c-proc.o $(MODULE_DIR)/gl518sm.o \ 
    29               $(MODULE_DIR)/eeprom.o $(MODULE_DIR)/w83781d.o  
     29              $(MODULE_DIR)/eeprom.o $(MODULE_DIR)/w83781d.o \ 
     30              $(MODULE_DIR)/lm80.o 
    3031 
    3132SRCHEADERFILES := $(MODULE_DIR)/sensors.h $(MODULE_DIR)/isa.h \ 
  • lm-sensors/trunk/src/gl518sm.c

    r112 r115  
    6666#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) 
    6767#define DIV_FROM_REG(val) (1 << (val)) 
     68 
     69#define ALARMS_FROM_REG(val) val 
    6870 
    6971#define BEEP_ENABLE_TO_REG(val) ((val)?0:1) 
     
    566568  else if (operation == SENSORS_PROC_REAL_READ) { 
    567569    gl518_update_client(client); 
    568     results[0] = data->alarms; 
     570    results[0] = ALARMS_FROM_REG(data->alarms); 
    569571    *nrels_mag = 1; 
    570572  } 
  • lm-sensors/trunk/src/lm78.c

    r114 r115  
    1  
    21/* 
    32    lm78.c - Part of lm_sensors, Linux kernel modules for hardware 
  • lm-sensors/trunk/src/lm80.c

    r113 r115  
    1  
    21/* 
    32    lm80.c - Part of lm_sensors, Linux kernel modules for hardware 
     
    4342#define LM80_REG_IN(nr) (0x20 + (nr)) 
    4443 
    45 #define LM80_REG_FAN_MIN(nr) (0x3b + (nr)) 
    46 #define LM80_REG_FAN(nr) (0x27 + (nr)) 
     44#define LM80_REG_FAN1_MIN 0x3c 
     45#define LM80_REG_FAN2_MIN 0x3d 
     46#define LM80_REG_FAN1 0x28 
     47#define LM80_REG_FAN2 0x29 
    4748 
    4849#define LM80_REG_TEMP 0x27 
    49 #define LM80_REG_TEMP_OVER 0x39 
    50 #define LM80_REG_TEMP_HYST 0x3a 
    51  
    52 #define LM80_REG_ALARM1 0x41 
    53 #define LM80_REG_ALARM2 0x42 
    54  
    55 #define LM80_REG_VID_FANDIV 0x47 
    56  
    57 #define LM80_REG_CONFIG 0x40 
    58 #define LM80_REG_CHIPID 0x49 
     50#define LM80_REG_TEMP_HOT_MAX 0x38 
     51#define LM80_REG_TEMP_HOT_HYST 0x39 
     52#define LM80_REG_TEMP_OS_MAX 0x3a 
     53#define LM80_REG_TEMP_OS_HYST 0x3b 
     54 
     55#define LM80_REG_CONFIG 0x00 
     56#define LM80_REG_ALARM1 0x01 
     57#define LM80_REG_ALARM2 0x02 
     58#define LM80_REG_MASK1 0x03 
     59#define LM80_REG_MASK2 0x04 
     60#define LM80_REG_FANDIV 0x05 
     61#define LM80_REG_RES 0x06 
    5962 
    6063 
    6164/* Conversions. Rounding is only done on the TO_REG variants. */ 
    62 #define IN_TO_REG(val,nr) (((((val) * 100000 / lm80_in_conv[nr]) + 8) / 16) \ 
    63                            & 0xff) 
    64 #define IN_FROM_REG(val,nr) (((val) *  16 * lm80_in_conv[nr]) / 100000) 
    65  
    66 #define FAN_TO_REG(val) ((val)==0?255:((1350000+(val))/((val)*2)) & 0xff) 
    67 #define FAN_FROM_REG(val) ((val)==0?-1:(val)==255?0:1350000/((val)*2)) 
    68  
    69 #define TEMP_TO_REG(val) (((val)<0?(((val)-5)/10)&0xff:((val)+5)/10) & 0xff) 
    70 #define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) 
    71  
    72 #define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ 
    73                            (val)>=0x06?0:205-(val)*5) 
    74 #define ALARMS_FROM_REG(val) (val) 
     65#define IN_TO_REG(val,nr) ((val) & 0xff) 
     66#define IN_FROM_REG(val,nr) (val) 
     67 
     68#define FAN_TO_REG(val,div) ((val)==0?255:\ 
     69                             ((1350000+(val)*(div))/((val)*(div)*2)) & 0xff) 
     70#define FAN_FROM_REG(val,div) ((val)==0?-1:\ 
     71                               (val)==255?0:1350000/((div)*(val)*2)) 
     72 
     73#define TEMP_FROM_REG(val) lm80_temp_from_reg(val) 
     74 
     75#define TEMP_LIMIT_TO_REG(val) (((val)<0?(((val)-50)/100)&0xff:\ 
     76                                           ((val)+50)/100) & 0xff) 
     77#define TEMP_LIMIT_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*100) 
     78 
     79#define ALARMS_FROM_REG(val) (val)  
    7580 
    7681#define DIV_FROM_REG(val) (1 << (val)) 
     
    7883 
    7984/* Initial limits */ 
    80 #define LM80_INIT_IN_0 (vid==350?280:vid) 
    81 #define LM80_INIT_IN_1 (vid==350?280:vid) 
    82 #define LM80_INIT_IN_2 330 
    83 #define LM80_INIT_IN_3 500 
    84 #define LM80_INIT_IN_4 1200 
    85 #define LM80_INIT_IN_5 -1200 
    86 #define LM80_INIT_IN_6 -500 
     85#define LM80_INIT_IN_0 190 
     86#define LM80_INIT_IN_1 190 
     87#define LM80_INIT_IN_2 190 
     88#define LM80_INIT_IN_3 190 
     89#define LM80_INIT_IN_4 190 
     90#define LM80_INIT_IN_5 190 
     91#define LM80_INIT_IN_6 190 
    8792 
    8893#define LM80_INIT_IN_PERCENTAGE 10 
     
    119124#define LM80_INIT_FAN_MIN_1 3000 
    120125#define LM80_INIT_FAN_MIN_2 3000 
    121 #define LM80_INIT_FAN_MIN_3 3000 
    122  
    123 #define LM80_INIT_TEMP_OVER 600 
    124 #define LM80_INIT_TEMP_HYST 500 
     126 
     127#define LM80_INIT_TEMP_OS_MAX 600 
     128#define LM80_INIT_TEMP_OS_HYST 500 
     129#define LM80_INIT_TEMP_HOT_MAX 700 
     130#define LM80_INIT_TEMP_HOT_HYST 600 
    125131 
    126132#ifdef MODULE 
     
    128134extern int cleanup_module(void); 
    129135#endif /* MODULE */ 
    130  
    131 /* This module may seem overly long and complicated. In fact, it is not so 
    132    bad. Quite a lot of bookkeeping is done. A real driver can often cut 
    133    some corners. */ 
    134136 
    135137/* For each registered LM80, we need to keep some data in memory. That 
     
    138140   allocated. */ 
    139141struct lm80_data { 
    140          struct semaphore lock; 
    141142         int sysctl_id; 
    142143 
     
    148149         u8 in_max[7];               /* Register value */ 
    149150         u8 in_min[7];               /* Register value */ 
    150          u8 fan[3];                  /* Register value */ 
    151          u8 fan_min[3];              /* Register value */ 
    152          u8 temp;                    /* Register value */ 
    153          u8 temp_over;               /* Register value */ 
    154          u8 temp_hyst;               /* Register value */ 
     151         u8 fan[2];                  /* Register value */ 
     152         u8 fan_min[2];              /* Register value */ 
    155153         u8 fan_div[2];              /* Register encoding, shifted right */ 
    156          u8 vid;                     /* Register encoding, combined */ 
     154         u16 temp;                   /* Register values, shifted right */ 
     155         u8 temp_hot_max;            /* Register value */ 
     156         u8 temp_hot_hyst;           /* Register value */ 
     157         u8 temp_os_max;             /* Register value */ 
     158         u8 temp_os_hyst;            /* Register value */ 
    157159         u16 alarms;                 /* Register encoding, combined */ 
    158160}; 
     
    163165 
    164166static int lm80_attach_adapter(struct i2c_adapter *adapter); 
    165 static int lm80_detect_smbus(struct i2c_adapter *adapter); 
    166167static int lm80_detach_client(struct i2c_client *client); 
    167 static int lm80_detach_smbus(struct i2c_client *client); 
    168168static int lm80_new_client(struct i2c_adapter *adapter, 
    169169                           struct i2c_client *new_client); 
     
    174174static void lm80_dec_use (struct i2c_client *client); 
    175175 
     176static long lm80_temp_from_reg(u16 regs); 
     177 
    176178static int lm80_read_value(struct i2c_client *client, u8 register); 
    177179static int lm80_write_value(struct i2c_client *client, u8 register, u8 value); 
     
    186188static void lm80_temp(struct i2c_client *client, int operation, int ctl_name, 
    187189                      int *nrels_mag, long *results); 
    188 static void lm80_vid(struct i2c_client *client, int operation, int ctl_name, 
    189                      int *nrels_mag, long *results); 
    190190static void lm80_alarms(struct i2c_client *client, int operation, int ctl_name, 
    191191                        int *nrels_mag, long *results); 
     
    240240  { LM80_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &sensors_proc_real, 
    241241    &sensors_sysctl_real, NULL, &lm80_fan }, 
    242   { LM80_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &sensors_proc_real, 
    243     &sensors_sysctl_real, NULL, &lm80_fan }, 
    244242  { LM80_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &sensors_proc_real, 
    245243    &sensors_sysctl_real, NULL, &lm80_temp }, 
    246   { LM80_SYSCTL_VID, "vid", NULL, 0, 0644, NULL, &sensors_proc_real, 
    247     &sensors_sysctl_real, NULL, &lm80_vid }, 
    248244  { LM80_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &sensors_proc_real, 
    249245    &sensors_sysctl_real, NULL, &lm80_fan_div }, 
     
    254250 
    255251 
    256 /* This function is called when: 
    257      * lm80_driver is inserted (when this module is loaded), for each 
    258        available adapter 
    259      * when a new adapter is inserted (and lm80_driver is still present) */ 
    260252int lm80_attach_adapter(struct i2c_adapter *adapter) 
    261 { 
    262     return lm80_detect_smbus(adapter); 
    263 } 
    264  
    265 /* This function is called whenever a client should be removed: 
    266     * lm80_driver is removed (when this module is unloaded) 
    267     * when an adapter is removed which has a lm80 client (and lm80_driver 
    268       is still present). */ 
    269 int lm80_detach_client(struct i2c_client *client) 
    270 { 
    271     return lm80_detach_smbus(client); 
    272 } 
    273  
    274 int lm80_detect_smbus(struct i2c_adapter *adapter) 
    275253{ 
    276254  int address,err; 
     
    290268    /* Real detection code goes here */ 
    291269 
    292     err = smbus_read_byte_data(adapter,address,LM80_REG_CHIPID) & 0xfe; 
    293  
    294270    printk("lm80.o: LM80 detected\n"); 
    295271    type_name = "lm80"; 
     
    298274 
    299275    /* Allocate space for a new client structure. To counter memory 
    300        ragmentation somewhat, we only do one kmalloc. */ 
     276       fragmentation somewhat, we only do one kmalloc. */ 
    301277    if (! (new_client = kmalloc(sizeof(struct i2c_client) +  
    302278                                sizeof(struct lm80_data), 
     
    340316} 
    341317 
    342 int lm80_detach_smbus(struct i2c_client *client) 
     318int lm80_detach_client(struct i2c_client *client) 
    343319{ 
    344320  int err,i; 
     
    386362  data = new_client->data; 
    387363  data->valid = 0; 
    388   data->lock = MUTEX; 
    389364  data->update_lock = MUTEX; 
    390365  return 0; 
     
    406381} 
    407382 
    408 /* Nothing here yet */ 
    409383void lm80_inc_use (struct i2c_client *client) 
    410384{ 
     
    414388} 
    415389 
    416 /* Nothing here yet */ 
    417390void lm80_dec_use (struct i2c_client *client) 
    418391{ 
     
    423396  
    424397 
    425 /* The SMBus locks itself, but ISA access must be locked explicitely!  
    426    We ignore the LM80 BUSY flag at this moment - it could lead to deadlocks, 
    427    would slow down the LM80 access and should not be necessary.  
    428    There are some ugly typecasts here, but the good new is - they should 
    429    nowhere else be necessary! */ 
     398long lm80_temp_from_reg(u16 temp) 
     399{ 
     400  long res; 
     401  res = ((temp & 0xff00) >> 8) * 10000 + ((temp & 0x10) >> 4) * 5000 + 
     402        ((temp & 0x20) >> 5) * 2500 + ((temp & 0x40) >> 6) * 1250 + 
     403        ((temp & 0x80) >> 7) * 625; 
     404  temp /= 100; 
     405  if (temp >= 0x80 * 100) 
     406    temp = - (0x100 * 100 - temp); 
     407  return temp; 
     408} 
     409 
    430410int lm80_read_value(struct i2c_client *client, u8 reg) 
    431411{ 
    432   int res; 
    433   if (i2c_is_isa_client(client)) { 
    434     down((struct semaphore *) (client->data)); 
    435     outb_p(reg,(((struct isa_client *) client)->isa_addr) +  
    436                LM80_ADDR_REG_OFFSET); 
    437     res = inb_p((((struct isa_client *) client)->isa_addr) +  
    438                 LM80_DATA_REG_OFFSET); 
    439     up((struct semaphore *) (client->data)); 
    440     return res; 
    441   } else 
    442     return smbus_read_byte_data(client->adapter,client->addr, reg); 
    443 } 
    444  
    445 /* The SMBus locks itself, but ISA access muse be locked explicitely!  
    446    We ignore the LM80 BUSY flag at this moment - it could lead to deadlocks, 
    447    would slow down the LM80 access and should not be necessary.  
    448    There are some ugly typecasts here, but the good new is - they should 
    449    nowhere else be necessary! */ 
     412  return smbus_read_byte_data(client->adapter,client->addr, reg); 
     413} 
     414 
    450415int lm80_write_value(struct i2c_client *client, u8 reg, u8 value) 
    451416{ 
    452   if (i2c_is_isa_client(client)) { 
    453     down((struct semaphore *) (client->data)); 
    454     outb_p(reg,((struct isa_client *) client)->isa_addr + LM80_ADDR_REG_OFFSET); 
    455     outb_p(value,((struct isa_client *) client)->isa_addr + LM80_DATA_REG_OFFSET); 
    456     up((struct semaphore *) (client->data)); 
    457     return 0; 
    458   } else 
    459     return smbus_write_byte_data(client->adapter, client->addr, reg,value); 
     417  return smbus_write_byte_data(client->adapter, client->addr, reg,value); 
    460418} 
    461419 
     
    463421void lm80_init_client(struct i2c_client *client) 
    464422{ 
    465   int vid; 
    466  
    467423  /* Reset all except Watchdog values and last conversion values 
    468      This sets fan-divs to 2, among others */ 
     424     This sets fan-divs to 2, among others. This makes most other 
     425     initializations unnecessary */ 
    469426  lm80_write_value(client,LM80_REG_CONFIG,0x80); 
    470  
    471   vid = lm80_read_value(client,LM80_REG_VID_FANDIV) & 0x0f; 
    472   vid |= (lm80_read_value(client,LM80_REG_CHIPID) & 0x01) >> 4; 
    473   vid = VID_FROM_REG(vid); 
     427  /* Set 11-bit temperature resolution */ 
     428  lm80_write_value(client,LM80_REG_RES,0x08); 
    474429 
    475430  lm80_write_value(client,LM80_REG_IN_MIN(0),IN_TO_REG(LM80_INIT_IN_MIN_0,0)); 
     
    487442  lm80_write_value(client,LM80_REG_IN_MIN(6),IN_TO_REG(LM80_INIT_IN_MIN_6,6)); 
    488443  lm80_write_value(client,LM80_REG_IN_MAX(6),IN_TO_REG(LM80_INIT_IN_MAX_6,6)); 
    489   lm80_write_value(client,LM80_REG_FAN_MIN(1),FAN_TO_REG(LM80_INIT_FAN_MIN_1)); 
    490   lm80_write_value(client,LM80_REG_FAN_MIN(2),FAN_TO_REG(LM80_INIT_FAN_MIN_2)); 
    491   lm80_write_value(client,LM80_REG_FAN_MIN(3),FAN_TO_REG(LM80_INIT_FAN_MIN_3)); 
    492   lm80_write_value(client,LM80_REG_TEMP_OVER,TEMP_TO_REG(LM80_INIT_TEMP_OVER)); 
    493   lm80_write_value(client,LM80_REG_TEMP_HYST,TEMP_TO_REG(LM80_INIT_TEMP_HYST)); 
     444  lm80_write_value(client,LM80_REG_FAN1_MIN,FAN_TO_REG(LM80_INIT_FAN_MIN_1,2)); 
     445  lm80_write_value(client,LM80_REG_FAN2_MIN,FAN_TO_REG(LM80_INIT_FAN_MIN_2,2)); 
     446  lm80_write_value(client,LM80_REG_TEMP_HOT_MAX, 
     447                   TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_MAX)); 
     448  lm80_write_value(client,LM80_REG_TEMP_HOT_HYST, 
     449                   TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_HYST)); 
     450  lm80_write_value(client,LM80_REG_TEMP_OS_MAX, 
     451                   TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_MAX)); 
     452  lm80_write_value(client,LM80_REG_TEMP_OS_HYST, 
     453                   TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_HYST)); 
    494454 
    495455  /* Start monitoring */ 
    496   lm80_write_value(client,LM80_REG_CONFIG, 
    497                    (lm80_read_value(client,LM80_REG_CONFIG) & 0xf7) | 0x01); 
    498    
     456  lm80_write_value(client,LM80_REG_CONFIG,0x01); 
    499457} 
    500458 
     
    506464  down(&data->update_lock); 
    507465 
    508   if ((jiffies - data->last_updated > HZ+HZ/2 ) || 
     466  if ((jiffies - data->last_updated > 2*HZ ) || 
    509467      (jiffies < data->last_updated) || ! data->valid) { 
    510468 
     
    517475      data->in_max[i] = lm80_read_value(client,LM80_REG_IN_MAX(i)); 
    518476    } 
    519     for (i = 1; i <= 3; i++) { 
    520       data->fan[i-1] = lm80_read_value(client,LM80_REG_FAN(i)); 
    521       data->fan_min[i-1] = lm80_read_value(client,LM80_REG_FAN_MIN(i)); 
    522     } 
    523     data->temp = lm80_read_value(client,LM80_REG_TEMP); 
    524     data->temp_over = lm80_read_value(client,LM80_REG_TEMP_OVER); 
    525     data->temp_hyst = lm80_read_value(client,LM80_REG_TEMP_HYST); 
    526     i = lm80_read_value(client,LM80_REG_VID_FANDIV); 
    527     data->vid = i & 0x0f; 
    528     data->vid |= (lm80_read_value(client,LM80_REG_CHIPID) & 0x01) >> 4; 
    529     data->fan_div[0] = (i >> 4) & 0x03; 
    530     data->fan_div[1] = i >> 6; 
     477    data->fan[0] = lm80_read_value(client,LM80_REG_FAN1); 
     478    data->fan_min[0] = lm80_read_value(client,LM80_REG_FAN1_MIN); 
     479    data->fan[1] = lm80_read_value(client,LM80_REG_FAN2); 
     480    data->fan_min[1] = lm80_read_value(client,LM80_REG_FAN2_MIN); 
     481    
     482    data->temp = (lm80_read_value(client,LM80_REG_TEMP) << 8) | 
     483                 (lm80_read_value(client,LM80_REG_RES) & 0xf0); 
     484    data->temp_os_max = lm80_read_value(client,LM80_REG_TEMP_OS_MAX); 
     485    data->temp_os_hyst = lm80_read_value(client,LM80_REG_TEMP_OS_HYST); 
     486    data->temp_hot_max = lm80_read_value(client,LM80_REG_TEMP_HOT_MAX); 
     487    data->temp_hot_hyst = lm80_read_value(client,LM80_REG_TEMP_HOT_HYST); 
     488 
     489    i = lm80_read_value(client,LM80_REG_FANDIV); 
     490    data->fan_div[0] = (i >> 2) & 0x03; 
     491    data->fan_div[1] = (i >> 4) & 0x03; 
    531492    data->alarms = lm80_read_value(client,LM80_REG_ALARM1) + 
    532                    (lm80_read_value(client,LM80_REG_ALARM2) >> 8); 
     493                   (lm80_read_value(client,LM80_REG_ALARM2) << 8); 
    533494    data->last_updated = jiffies; 
    534495    data->valid = 1; 
     
    588549  else if (operation == SENSORS_PROC_REAL_READ) { 
    589550    lm80_update_client(client); 
    590     results[0] = FAN_FROM_REG(data->fan_min[nr-1]); 
    591     results[1] = FAN_FROM_REG(data->fan[nr-1]); 
     551    results[0] = FAN_FROM_REG(data->fan_min[nr-1],data->fan_div[nr-1]); 
     552    results[1] = FAN_FROM_REG(data->fan[nr-1],data->fan_div[nr-1]); 
    592553    *nrels_mag = 2; 
    593554  } else if (operation == SENSORS_PROC_REAL_WRITE) { 
    594555    if (*nrels_mag >= 1) { 
    595       data->fan_min[nr-1] = FAN_TO_REG(results[0]); 
    596       lm80_write_value(client,LM80_REG_FAN_MIN(nr),data->fan_min[nr-1]); 
     556      data->fan_min[nr-1] = FAN_TO_REG(results[0],data->fan_div[nr-1]); 
     557      lm80_write_value(client,nr==1?LM80_REG_FAN1_MIN:LM80_REG_FAN2_MIN, 
     558                       data->fan_min[nr-1]); 
    597559    } 
    598560  } 
     
    608570  else if (operation == SENSORS_PROC_REAL_READ) { 
    609571    lm80_update_client(client); 
    610     results[0] = TEMP_FROM_REG(data->temp_over); 
    611     results[1] = TEMP_FROM_REG(data->temp_hyst); 
    612     results[2] = TEMP_FROM_REG(data->temp); 
    613     *nrels_mag = 3; 
     572    results[0] = TEMP_LIMIT_FROM_REG(data->temp_hot_max); 
     573    results[1] = TEMP_LIMIT_FROM_REG(data->temp_hot_hyst); 
     574    results[2] = TEMP_LIMIT_FROM_REG(data->temp_os_max); 
     575    results[3] = TEMP_LIMIT_FROM_REG(data->temp_os_hyst); 
     576    results[4] = TEMP_FROM_REG(data->temp); 
     577    *nrels_mag = 5; 
    614578  } else if (operation == SENSORS_PROC_REAL_WRITE) { 
    615579    if (*nrels_mag >= 1) { 
    616       data->temp_over = TEMP_TO_REG(results[0]); 
    617       lm80_write_value(client,LM80_REG_TEMP_OVER,data->temp_over); 
     580      data->temp_hot_max = TEMP_LIMIT_TO_REG(results[0]); 
     581      lm80_write_value(client,LM80_REG_TEMP_HOT_MAX,data->temp_hot_max); 
    618582    } 
    619583    if (*nrels_mag >= 2) { 
    620       data->temp_hyst = TEMP_TO_REG(results[1]); 
    621       lm80_write_value(client,LM80_REG_TEMP_HYST,data->temp_hyst); 
    622     } 
    623   } 
    624 } 
    625  
    626 void lm80_vid(struct i2c_client *client, int operation, int ctl_name, 
    627               int *nrels_mag, long *results) 
    628 { 
    629   struct lm80_data *data = client->data; 
    630   if (operation == SENSORS_PROC_REAL_INFO) 
    631     *nrels_mag = 2; 
    632   else if (operation == SENSORS_PROC_REAL_READ) { 
    633     lm80_update_client(client); 
    634     results[0] = VID_FROM_REG(data->vid); 
    635     *nrels_mag = 1; 
     584      data->temp_hot_hyst = TEMP_LIMIT_TO_REG(results[1]); 
     585      lm80_write_value(client,LM80_REG_TEMP_HOT_HYST,data->temp_hot_hyst); 
     586    } 
     587    if (*nrels_mag >= 3) { 
     588      data->temp_os_max = TEMP_LIMIT_TO_REG(results[2]); 
     589      lm80_write_value(client,LM80_REG_TEMP_OS_MAX,data->temp_os_max); 
     590    } 
     591    if (*nrels_mag >= 4) { 
     592      data->temp_os_hyst = TEMP_LIMIT_TO_REG(results[3]); 
     593      lm80_write_value(client,LM80_REG_TEMP_OS_HYST,data->temp_os_hyst); 
     594    } 
    636595  } 
    637596} 
     
    665624    *nrels_mag = 3; 
    666625  } else if (operation == SENSORS_PROC_REAL_WRITE) { 
    667     old = lm80_read_value(client,LM80_REG_VID_FANDIV); 
     626    old = lm80_read_value(client,LM80_REG_FANDIV); 
    668627    if (*nrels_mag >= 2) { 
    669628      data->fan_div[1] = DIV_TO_REG(results[1]); 
    670       old = (old & 0x3f) | (data->fan_div[1] << 6); 
     629      old = (old & 0xcf) | (data->fan_div[1] << 4); 
    671630    } 
    672631    if (*nrels_mag >= 1) { 
    673632      data->fan_div[0] = DIV_TO_REG(results[0]); 
    674       old = (old & 0xcf) | (data->fan_div[0] << 4); 
    675       lm80_write_value(client,LM80_REG_VID_FANDIV,old); 
     633      old = (old & 0xf3) | (data->fan_div[0] << 2); 
     634      lm80_write_value(client,LM80_REG_FANDIV,old); 
    676635    } 
    677636  } 
  • lm-sensors/trunk/src/sensors.h

    r112 r115  
    8888#define I2C_DRIVERID_EEPROM 1005 
    8989#define I2C_DRIVERID_W83781D 1006 
     90#define I2C_DRIVERID_LM80 1007 
    9091 
    9192/* Sysctl IDs */ 
     
    199200#define EEPROM_SYSCTL8 1007 
    200201 
     202#define LM80_SYSCTL_IN0 1000  /* Volts * 100 */ 
     203#define LM80_SYSCTL_IN1 1001 
     204#define LM80_SYSCTL_IN2 1002 
     205#define LM80_SYSCTL_IN3 1003 
     206#define LM80_SYSCTL_IN4 1004 
     207#define LM80_SYSCTL_IN5 1005 
     208#define LM80_SYSCTL_IN6 1006 
     209#define LM80_SYSCTL_FAN1 1101 /* Rotations/min */ 
     210#define LM80_SYSCTL_FAN2 1102 
     211#define LM80_SYSCTL_TEMP 1250 /* Degrees Celcius * 100 */ 
     212#define LM80_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ 
     213#define LM80_SYSCTL_ALARMS 2001 /* bitvector */ 
     214 
     215#define LM80_ALARM_IN0 0x0001 
     216#define LM80_ALARM_IN1 0x0002 
     217#define LM80_ALARM_IN2 0x0004 
     218#define LM80_ALARM_IN3 0x0008 
     219#define LM80_ALARM_IN4 0x0010 
     220#define LM80_ALARM_IN5 0x0020 
     221#define LM80_ALARM_IN6 0x0040 
     222#define LM80_ALARM_FAN1 0x0400 
     223#define LM80_ALARM_FAN2 0x0800 
     224#define LM80_ALARM_TEMP_HOT 0x0100 
     225#define LM80_ALARM_TEMP_OS 0x2000 
     226#define LM80_ALARM_CHAS 0x1000 
     227#define LM80_ALARM_BTI 0x0200 
     228#define LM80_ALARM_INT_IN 0x0080 
    201229#endif /* def SENSORS_SENSORS_H */