Changeset 289

Show
Ignore:
Timestamp:
03/02/99 04:48:13 (10 years ago)
Author:
kmalkki
Message:

(Kyösti) Improved support for the gl518 revision 00

Code written by Ludovic Drolez (ldrolez@usa.net)
All voltages are now readable for the rev 00 but the read is blocked for 10
seconds because of the needed comparisons.
Currently voltages are readable in /proc only.
This functionality can be enabled at module-load with parameter readall:

insmod gl518 readall=1

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lm-sensors/trunk/TODO

    r269 r289  
    3838* Test SIS5595(/91/98) sensor support. Write generic i2c support.  
    3939  Thomas Dickel <Thomas.Dickel@mni.fh-giessen.de> owns one SIS5595. 
    40   The sensor data must be added to lib/chips 
     40* Make GL518SM rev 00 voltage iteration run as a kernel thread. 
     41  Add libsensors support for the new readable registers. 
  • lm-sensors/trunk/kernel/chips/gl518sm.c

    r214 r289  
    22    gl518sm.c - Part of lm_sensors, Linux kernel modules for hardware 
    33                monitoring 
    4     Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
     4    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>, 
     5                              Kyösti Mälkki <kmalkki@cc.hut.fi> 
    56 
    67    This program is free software; you can redistribute it and/or modify 
     
    1718    along with this program; if not, write to the Free Software 
    1819    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
     20 
    1921*/ 
    2022 
     
    2527#include "i2c.h" 
    2628#include "version.h" 
     29#include "compat.h" 
     30 
     31/* Defining this will enable debug messages for the voltage iteration 
     32   code used with rev 0 ICs */ 
     33#undef DEBUG_VIN 
    2734 
    2835/* Many GL518 constants specified below */ 
     
    5360 
    5461/* Conversions. Rounding is only done on the TO_REG variants. */ 
     62 
    5563#define TEMP_TO_REG(val) (((((val)<0?(val)-5:(val)+5) / 10) + 119) & 0xff) 
    5664#define TEMP_FROM_REG(val) (((val) - 119) * 10) 
     
    119127         char valid;                 /* !=0 if following fields are valid */ 
    120128         unsigned long last_updated; /* In jiffies */ 
     129         unsigned long last_updated_v00;  
     130                                     /* In jiffies (used only by rev00 chips) */ 
    121131 
    122132         u8 voltage[4];              /* Register values; [0] = VDD */ 
     
    130140         u8 alarms,beeps;            /* Register value */ 
    131141         u8 fan_div[2];              /* Register encoding, shifted right */ 
    132          u8 beep_enable;             /* Boolean */ 
     142         u8 beep_enable;             /* Boolean */       
    133143}; 
     144 
     145/* load time parameter that says if we want to spend 10 seconds for 
     146   reading all voltages from a GL518 rev 0, or if we want to read zeros */ 
     147int readall = 0; 
    134148 
    135149#ifdef MODULE 
    136150extern int init_module(void); 
    137151extern int cleanup_module(void); 
     152MODULE_PARM(readall,"i"); 
    138153#endif /* MODULE */ 
    139154 
     
    425440#endif 
    426441 
    427     if (data->revision != 0x00) { 
    428       data->voltage[0] = gl518_read_value(client,GL518_REG_VDD); 
    429       data->voltage[1] = gl518_read_value(client,GL518_REG_VIN1); 
    430       data->voltage[2] = gl518_read_value(client,GL518_REG_VIN2); 
    431     } 
    432     data->voltage[3] = gl518_read_value(client,GL518_REG_VIN3); 
     442    data->alarms = gl518_read_value(client,GL518_REG_INT); 
     443    data->beeps = gl518_read_value(client,GL518_REG_ALARM); 
    433444 
    434445    val = gl518_read_value(client,GL518_REG_VDD_LIMIT); 
     
    445456    data->voltage_max[3] = (val >> 8) & 0xff; 
    446457 
     458    if (data->revision != 0x00) { 
     459      data->voltage[0] = gl518_read_value(client,GL518_REG_VDD); 
     460      data->voltage[1] = gl518_read_value(client,GL518_REG_VIN1); 
     461      data->voltage[2] = gl518_read_value(client,GL518_REG_VIN2); 
     462    } else { 
     463      if (!readall) { 
     464        data->voltage[0] = 0; 
     465        data->voltage[1] = 0; 
     466        data->voltage[2] = 0; 
     467      } 
     468    } 
     469    data->voltage[3] = gl518_read_value(client,GL518_REG_VIN3); 
     470 
    447471    val = gl518_read_value(client,GL518_REG_FAN_COUNT); 
    448472    data->fan[0] = (val >> 8) & 0xff; 
     
    456480    data->temp_over = gl518_read_value(client,GL518_REG_TEMP_OVER); 
    457481    data->temp_hyst = gl518_read_value(client,GL518_REG_TEMP_HYST); 
    458  
    459     data->alarms = gl518_read_value(client,GL518_REG_INT); 
    460     data->beeps = gl518_read_value(client,GL518_REG_ALARM); 
    461482 
    462483    val = gl518_read_value(client,GL518_REG_MISC); 
     
    472493} 
    473494 
     495/* Similar to gl518_update_client() but updates vdd, vin1, vin2 values  
     496   by doing slow and multiple comparisons for the GL518SM rev 00 that 
     497   lacks support for direct reading of these values. 
     498   (added by Ludovic Drolez (ldrolez@usa.net) */ 
     499 
     500void gl518_update_client_rev00(struct i2c_client *client) 
     501{ 
     502  struct gl518_data *data = client->data; 
     503  struct wait_queue *wait = NULL; 
     504  int j, min, max[3], delta; 
     505 
     506  down(&data->update_lock); 
     507 
     508#ifndef DEBUG_VIN 
     509  /* as that update is slow, we consider the data valid for 30 seconds */ 
     510  if (jiffies - data->last_updated_v00 > 30*HZ ) { 
     511#else 
     512  if (jiffies - data->last_updated_v00 > HZ+HZ/2 ) { 
     513#endif 
     514 
     515     /* disable audible alarm */ 
     516     gl518_write_value(client,GL518_REG_CONF, 
     517                        (gl518_read_value(client,GL518_REG_CONF) & 0xfb)); 
     518 
     519    min = 1; 
     520    max[0] = VDD_TO_REG(GL518_INIT_VDD); 
     521    max[1] = IN_TO_REG(GL518_INIT_VIN_1);  
     522    max[2] = IN_TO_REG(GL518_INIT_VIN_2); 
     523    delta = 32; 
     524    do {                         
     525      gl518_write_value(client,GL518_REG_VDD_LIMIT,(max[0] << 8) | min); 
     526      gl518_write_value(client,GL518_REG_VIN1_LIMIT,(max[1] << 8) | min); 
     527      gl518_write_value(client,GL518_REG_VIN2_LIMIT,(max[2] << 8) | min); 
     528 
     529      /* we wait now 1.5 seconds before comparing */ 
     530      current->state = TASK_INTERRUPTIBLE; 
     531      schedule_timeout(HZ + HZ/2); 
     532 
     533      /* read comparators */     
     534      j = gl518_read_value(client,GL518_REG_INT); 
     535      if ((j & 1) == 0) { 
     536        max[0] = max[0] - delta;     
     537      } else { 
     538        max[0] = max[0] + delta; 
     539      } 
     540      if ((j & 2) == 0) { 
     541        max[1] = max[1] - delta;     
     542      } else { 
     543        max[1] = max[1] + delta; 
     544      } 
     545      if ((j & 4) == 0) { 
     546        max[2] = max[2] - delta;     
     547      } else { 
     548        max[2] = max[2] + delta; 
     549      } 
     550      delta >>= 1; 
     551#ifdef DEBUG_VIN 
     552      printk("Iterations: %3d %3d %3d \n", max[0], max[1], max[2]); 
     553#endif 
     554    } while (delta != 0); 
     555     
     556    /* do a final comparison to get to least significant bit */ 
     557    gl518_write_value(client,GL518_REG_VDD_LIMIT,(max[0] << 8) | min); 
     558    gl518_write_value(client,GL518_REG_VIN1_LIMIT,(max[1] << 8) | min); 
     559    gl518_write_value(client,GL518_REG_VIN2_LIMIT,(max[2] << 8) | min); 
     560  
     561    /* we wait now 1.5 seconds before comparing */ 
     562    current->state = TASK_INTERRUPTIBLE; 
     563    schedule_timeout(HZ + HZ/2); 
     564 
     565    /* read comparators */       
     566    j = gl518_read_value(client,GL518_REG_INT); 
     567    if ((j & 1) == 0) max[0]--; 
     568    if ((j & 2) == 0) max[1]--; 
     569    if ((j & 4) == 0) max[2]--; 
     570 
     571#ifdef DEBUG_VIN 
     572  if (data->revision) { 
     573     printk("Avdd: Meter: %3d, Search: %3d, Diff: %3d mV\n", 
     574             data->voltage[0], max[0], (max[0] - data->voltage[0]) * 23); 
     575     printk("Vin1: Meter: %3d, Search: %3d, Diff: %3d mV\n", 
     576             data->voltage[1], max[1], (max[1] - data->voltage[1]) * 19); 
     577     printk("Vin2: Meter: %3d, Search: %3d, Diff: %3d mV\n", 
     578             data->voltage[2], max[2], (max[2] - data->voltage[2]) * 19); 
     579  } else 
     580     printk("No voltage meter to read on rev 00 ICs\n");      
     581#endif   
     582 
     583    /* update voltages values */     
     584    data->voltage[0] = max[0]; 
     585    data->voltage[1] = max[1]; 
     586    data->voltage[2] = max[2]; 
     587     
     588    /* restore original comparator values */ 
     589    gl518_write_value(client,GL518_REG_VDD_LIMIT, 
     590                      (data->voltage_max[0] << 8) | data->voltage_min[0]); 
     591    gl518_write_value(client,GL518_REG_VIN1_LIMIT, 
     592                      (data->voltage_max[1] << 8) | data->voltage_min[1]); 
     593    gl518_write_value(client,GL518_REG_VIN2_LIMIT, 
     594                      (data->voltage_max[2] << 8) | data->voltage_min[2]); 
     595 
     596    data->last_updated_v00 = jiffies; 
     597     
     598    /* reset audible alarm state */ 
     599    gl518_write_value(client,GL518_REG_CONF, 
     600           (gl518_read_value(client,GL518_REG_CONF) & 0xfb) |  
     601           (data->beep_enable << 2)); 
     602  } 
     603  up(&data->update_lock); 
     604} 
    474605 
    475606void gl518_temp(struct i2c_client *client, int operation, int ctl_name, 
     
    508639  else if (operation == SENSORS_PROC_REAL_READ) { 
    509640    gl518_update_client(client); 
     641#ifndef DEBUG_VIN     
     642    if ((data->revision == 0x00) && (nr != 3) && readall) 
     643       /* only update VDD, VIN1, VIN2 voltages */ 
     644       gl518_update_client_rev00(client); 
     645#else 
     646    gl518_update_client_rev00(client); 
     647#endif 
    510648    results[0] = nr?IN_FROM_REG(data->voltage_min[nr]): 
    511                     VDD_FROM_REG(data->voltage_min[nr]); 
     649                    VDD_FROM_REG(data->voltage_min[nr]); 
    512650    results[1] = nr?IN_FROM_REG(data->voltage_max[nr]): 
    513                      VDD_FROM_REG(data->voltage_max[nr]); 
    514     if ((data->revision == 0x00) && (nr != 3)) 
    515       results[2] = 0; 
    516     else 
    517       results[2] = nr?IN_FROM_REG(data->voltage[nr]): 
    518                       VDD_FROM_REG(data->voltage[nr]); 
     651                    VDD_FROM_REG(data->voltage_max[nr]); 
     652    results[2] = nr?IN_FROM_REG(data->voltage[nr]): 
     653                    VDD_FROM_REG(data->voltage[nr]); 
    519654    *nrels_mag = 3; 
    520655  } else if (operation == SENSORS_PROC_REAL_WRITE) { 
     
    678813 
    679814#endif /* MODULE */ 
    680