Changeset 2660

Show
Ignore:
Timestamp:
08/13/04 21:29:33 (9 years ago)
Author:
mmh
Message:

Added support and documentation for:

  • reading #VRDHOT inputs
  • reading GPIO pins (input only for now)
  • reading alarms status
  • #PROCHOT override control
  • #PROCHOT sampling interval control
  • Manual PWM output control
  • PWM output frequency control

Also, some whitespace cleanup in the driver.

Location:
lm-sensors/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/doc/chips/lm93

    r2653 r2660  
    2020  Set to zero to disable some initializations (default is 1) 
    2121* disable_block: integer 
    22   Set to non-zero to disable SMBus block data transactions (default is 0) 
     22  A "0" allows SMBus block data transactions if the host supports them.  A "1" 
     23  disables SMBus block data transactions.  The default is 0. 
    2324* vccp_limit_type: integer array (2) 
    2425  Configures in7 and in8 limit type, where 0 means absolute and non-zero 
     
    8788range from 0-255 where 0 indicates no throttling, and 255 indicates > 99.6%. 
    8889 
     90The monitoring intervals for the two #PROCHOT signals is also configurable. 
     91These intervals can be found in the /proc file prochot_interval.  There are 
     92two values in this file: one each for #P1_PROCHOT and #P2_PROCHOT, res- 
     93pectively.  Selecting a value not in this list will cause the driver to 
     94use the next largest interval.  The available intervals are: 
     95 
     96#PROCHOT intervals: 0.73, 1.46, 2.9, 5.8, 11.7, 23.3, 46.6, 93.2, 186, 372 
     97 
    8998It is possible to configure the LM93 to logically short the two #PROCHOT 
    9099signals.  I.e. when #P1_PROCHOT is asserted, the LM93 will automatically 
     
    92101non-zero integer to the /proc file prochot_short. 
    93102 
     103The LM93 can also override the #PROCHOT pins by driving a PWM signal onto 
     104one or both of them.  When overridden, the signal has a period of 3.56 mS, 
     105a minimum pulse width of 5 clocks (at 22.5kHz => 6.25% duty cycle), and 
     106a maximum pulse width of 80 clocks (at 22.5kHz => 99.88% duty cycle). 
     107 
     108The /proc file prochot_override has three values.  The first two are boolean 
     109integers which enable/disable the override funtion for #P1_PROCHOT and  
     110#P2_PROCHOT, the third value is 0-15 where 0 indicates minimum duty cycle 
     111and 15 indicates maximum. 
     112 
     113#VRD_HOT: 
     114 
     115The LM93 can monitor two #VRD_HOT signals. The results are found in the 
     116/proc files vrdhot1 and vrdhot2. There is one value per file: a boolean for 
     117which 1 indicates #VRD_HOT is asserted and 0 indicates it is negated. These 
     118files are read-only. 
    94119 
    95120Smart Tach Mode: 
     
    105130Smart tach mode is enabled by the driver by writing 1 or 2 (associating the 
    106131the fan tachometer with a pwm) to the /proc file fan<n>_smart_tach.  A zero 
    107 will disable the function for that fan. 
     132will disable the function for that fan.  Note that Smart tach mode cannot be 
     133enabled if the PWM output frequency is 22500 Hz (see below). 
     134 
     135Manual PWM: 
     136 
     137The LM93 has a fixed or override mode for the two PWM outputs (although, there 
     138are still some conditions that will override even this mode - see section 
     13915.10.6 of the datasheet for details.)  The /proc files pwm1 and pwm2 are 
     140used to enable and control this mode.  The first value of the file is an  
     141integer (0-255) where 0 is 0% duty cycle, and 255 is 100%.  The second value 
     142is a boolean integer where 0 disables and 1 enables the manual control mode. 
     143Note that the duty cycle values are constrained by the hardware. Selecting 
     144a value which is not available will cause the driver to use the next largest 
     145value.  Also note: when manual PWM mode is disabled, the first value of the 
     146/proc files indicates the current duty cycle chosen by the h/w. 
     147 
     148PWM Output Frequency: 
     149 
     150The LM93 supports several different frequencies for the PWM output channels. 
     151The /proc files pwm1_freq and pwm2_freq are used to select the frequency. The 
     152frequency values are constrained by the hardware.  Selecting a value which is 
     153not available will cause the driver to use the next largest value.  Also note 
     154that this parameter has implications for the Smart Tach Mode (see above). 
     155 
     156PWM Output Frequencies: 12, 36, 48, 60, 72, 84, 96, 22500 (h/w default) 
     157 
     158GPIO Pins: 
     159 
     160The LM93 can monitor the logic level of four dedicated GPIO pins as well as the 
     161four tach input pins.  GPIO0-GPIO3 correspond to (fan) tach 1-4, respectively. 
     162All eight GPIOs are read by reading the bitmask in the /proc file gpio.  The 
     163LSB is GPIO0, and the MSB is GPIO7. 
    108164 
    109165LM93 Unique /proc Files 
     
    117173        prochot_short           enable or disable logical #PROCHOT pin short 
    118174 
     175        prochot_override        force #PROCHOT assertion as PWM 
     176 
     177        prochot_interval        #PROCHOT PWM sampling interval 
     178 
     179        vrdhot<n>               0 means negated, 1 means asserted 
     180 
    119181        fan<n>_smart_tach       enable or disable smart tach mode 
     182 
     183        gpio                    input state of 8 GPIO pins; read-only 
    120184 
    121185 
  • lm-sensors/trunk/kernel/chips/lm93.c

    r2659 r2660  
    9797#define LM93_REG_TEMP_MAX(nr)           (0x79 + (nr) * 2) 
    9898 
     99/* temp[1-4]_auto_boost (nr => 0-3) */ 
     100#define LM93_REG_TEMP_FAN_BOOST(nr)     (0x80 + (nr)) 
     101 
    99102/* #PROCHOT inputs: prochot1-prochot2 (nr => 0-1) */ 
    100103#define LM93_REG_PROCHOT_CUR(nr)        (0x67 + (nr) * 2) 
     
    106109#define LM93_REG_FAN_MIN(nr)            (0xb4 + (nr) * 2) 
    107110 
    108 /* pwm outputs: pwm1-pwm2 (nr => 0-1) */ 
    109 #define LM93_REG_PWM_CTL1(nr)           (0xc8 + (nr) * 4) 
    110 #define LM93_REG_PWM_CTL2(nr)           (0xc9 + (nr) * 4) 
    111 #define LM93_REG_PWM_CTL3(nr)           (0xca + (nr) * 4) 
    112 #define LM93_REG_PWM_CTL4(nr)           (0xcb + (nr) * 4) 
     111/* pwm outputs: pwm1-pwm2 (nr => 0-1, reg => 0-3) */ 
     112#define LM93_REG_PWM_CTL(nr,reg)        (0xc8 + (reg) + (nr) * 4) 
     113#define LM93_PWM_CTL1   0 
     114#define LM93_PWM_CTL2   1 
     115#define LM93_PWM_CTL3   2 
     116#define LM93_PWM_CTL4   3 
     117 
     118/* GPIO input state */ 
     119#define LM93_REG_GPI                    0x6b 
    113120 
    114121/* vid inputs: vid1-vid2 (nr => 0-1) */ 
     
    117124/* vccp1 & vccp2: VID relative inputs (nr => 0-1) */ 
    118125#define LM93_REG_VCCP_LIMIT_OFF(nr)     (0xb2 + (nr)) 
     126 
     127/* temp[1-4]_auto_boost_hyst */ 
     128#define LM93_REG_BOOST_HYST_12          0xc0 
     129#define LM93_REG_BOOST_HYST_34          0xc1 
     130 
     131/* temp[1-4]_auto_pwm_[min|hyst] */ 
     132#define LM93_REG_MIN_PWM_HYST_12        0xc3 
     133#define LM93_REG_MIN_PWM_HYST_34        0xc4 
     134 
     135/* prochot_override & prochot_interval */ 
     136#define LM93_REG_PROCHOT_OVERRIDE       0xc6 
     137#define LM93_REG_PROCHOT_INTERVAL       0xc7 
     138 
     139/* temp[1-4]_auto_base (nr => 0-3) */ 
     140#define LM93_REG_TEMP_BASE(nr)          (0xd0 + (nr)) 
     141 
     142/* temp[1-4]_auto_offsets (step => 0-11) */ 
     143#define LM93_REG_TEMP_OFFSET(step)      (0xd4 + (step)) 
     144 
     145/* #PROCHOT & #VRDHOT PWM ramp control */ 
     146#define LM93_REG_PWM_RAMP_CTL           0xbf 
    119147 
    120148/* miscellaneous */ 
     
    301329} 
    302330 
    303 /* <TODO> add conversion routines here */ 
     331/* PROCHOT-OVERRIDE; 0-15, 0 is 6.25%, 15 is 99.88% 
     332 * REG: (same) */ 
     333static u8 LM93_PROCHOT_OVERRIDE_TO_REG(int force1, int force2, long prochot) 
     334{ 
     335        u8 result = 0; 
     336 
     337        result |= force1 ? 0x80 : 0x00; 
     338        result |= force2 ? 0x40 : 0x00; 
     339        prochot = SENSORS_LIMIT(prochot, 0, 15); 
     340        result |= prochot; 
     341        return result; 
     342} 
     343 
     344/* PROCHOT-INTERVAL: 73 - 37200 (1/100 seconds) 
     345 * REG: 0-9 as mapped below */ 
     346static int lm93_interval_map[10] = { 
     347        73, 146, 290, 580, 1170, 2330, 4660, 9320, 18600, 37200, 
     348}; 
     349 
     350static int LM93_INTERVAL_FROM_REG(u8 reg) 
     351{ 
     352        return lm93_interval_map[reg & 0x0f]; 
     353} 
     354 
     355/* round up to nearest match */ 
     356static u8 LM93_INTERVAL_TO_REG(long interval) 
     357{ 
     358        int i; 
     359        for (i = 0; i < 9; i++) 
     360                if (interval <= lm93_interval_map[i]) 
     361                        break; 
     362 
     363        /* can fall through with i==9 */ 
     364        return (u8)i; 
     365} 
     366 
     367/* PWM: 0-255 per sensors documentation 
     368   REG: 0-13 as mapped below... *left* justified */ 
     369typedef enum { LM93_PWM_MAP_HI_FREQ, LM93_PWM_MAP_LO_FREQ } pwm_freq_t; 
     370static int lm93_pwm_map[2][14] = { 
     371        { 
     372                0x00, /*   0.00% */ 0x40, /*  25.00% */ 
     373                0x50, /*  31.25% */ 0x60, /*  37.50% */ 
     374                0x70, /*  43.75% */ 0x80, /*  50.00% */ 
     375                0x90, /*  56.25% */ 0xa0, /*  62.50% */ 
     376                0xb0, /*  68.75% */ 0xc0, /*  75.00% */ 
     377                0xd0, /*  81.25% */ 0xe0, /*  87.50% */ 
     378                0xf0, /*  93.75% */ 0xff, /* 100.00% */ 
     379        }, 
     380        { 
     381                0x00, /*   0.00% */ 0x40, /*  25.00% */ 
     382                0x49, /*  28.57% */ 0x52, /*  32.14% */ 
     383                0x5b, /*  35.71% */ 0x64, /*  39.29% */ 
     384                0x6d, /*  42.86% */ 0x76, /*  46.43% */ 
     385                0x80, /*  50.00% */ 0x89, /*  53.57% */ 
     386                0x92, /*  57.14% */ 0xb6, /*  71.43% */ 
     387                0xdb, /*  85.71% */ 0xff, /* 100.00% */ 
     388        }, 
     389}; 
     390 
     391static int LM93_PWM_FROM_REG(u8 reg, pwm_freq_t freq) 
     392{ 
     393        return lm93_pwm_map[freq][reg >> 4 & 0x0f]; 
     394} 
     395 
     396/* round up to nearest match */ 
     397static u8 LM93_PWM_TO_REG(int pwm, pwm_freq_t freq) 
     398{ 
     399        int i; 
     400        for (i = 0; i < 13; i++) 
     401                if (pwm <= lm93_pwm_map[freq][i]) 
     402                        break; 
     403 
     404        /* can fall through with i==13 */ 
     405        return (u8)(i << 4); 
     406} 
     407 
     408/* PWM FREQ: HZ 
     409   REG: 0-7 as mapped below */ 
     410static int lm93_pwm_freq_map[8] = { 
     411        22500, 96, 84, 72, 60, 48, 36, 12 
     412}; 
     413 
     414static int LM93_PWM_FREQ_FROM_REG(u8 reg) 
     415{ 
     416        return lm93_pwm_freq_map[reg & 0x07]; 
     417} 
     418 
     419/* round up to nearest match */ 
     420static u8 LM93_PWM_FREQ_TO_REG(int freq) 
     421{ 
     422        int i; 
     423        for (i = 7; i > 0; i--) 
     424                if (freq <= lm93_pwm_freq_map[i]) 
     425                        break; 
     426 
     427        /* can fall through with i==0 */ 
     428        return (u8)i; 
     429} 
     430 
     431/* GPIO: 0-255, GPIO0 is LSB 
     432 * REG: inverted */ 
     433static unsigned LM93_GPI_FROM_REG(u8 reg) 
     434{ 
     435        return ~reg & 0xff; 
     436} 
     437 
     438/* ALARMS: SYSCTL format described further below 
     439   REG: 64 bits in 8 registers, as immediately below */ 
     440struct block1_t { 
     441        u8 host_status_1; 
     442        u8 host_status_2; 
     443        u8 host_status_3; 
     444        u8 host_status_4; 
     445        u8 p1_prochot_status; 
     446        u8 p2_prochot_status; 
     447        u8 gpi_status; 
     448        u8 fan_status; 
     449}; 
     450 
     451static unsigned LM93_ALARMS_FROM_REG(struct block1_t b1) 
     452{ 
     453        unsigned result; 
     454        result  = b1.host_status_2; 
     455        result |= b1.host_status_3 << 8; 
     456        result |= (b1.fan_status & 0x04) << 16; 
     457        result |= (b1.p1_prochot_status & 0x80) << 13; 
     458        result |= (b1.p2_prochot_status & 0x80) << 14; 
     459        result |= (b1.host_status_4 & 0xfc) << 20; 
     460        result |= (b1.host_status_1 & 0x07) << 28; 
     461        return result; 
     462} 
    304463 
    305464/* For each registered client, we need to keep some data in memory. That 
     
    322481 
    323482        /* register values, arranged by block read groups */ 
    324         struct { 
    325                 u8 host_status_1; 
    326                 u8 host_status_2; 
    327                 u8 host_status_3; 
    328                 u8 host_status_4; 
    329                 u8 p1_prochot_status; 
    330                 u8 p2_prochot_status; 
    331                 u8 gpi_status; 
    332                 u8 fan_status; 
    333         } block1; 
     483        struct block1_t block1; 
    334484 
    335485        /* temp1 - temp4: unfiltered readings 
     
    355505        u16 block8[4]; 
    356506 
    357         /* more register values */ 
     507        /* pwm control registers (2 pwms, 4 regs) */ 
     508        u8 block9[2][4]; 
    358509 
    359510        /* master config register */ 
     
    368519        /* vccp1 & vccp2 (in7 & in8): VID relative limits (register format) */ 
    369520        u8 vccp_limits[2]; 
     521 
     522        /* GPIO input state (register format, i.e. inverted) */ 
     523        u8 gpi; 
     524 
     525        /* #PROCHOT override (register format) */ 
     526        u8 prochot_override; 
     527 
     528        /* #PROCHOT intervals (register format) */ 
     529        u8 prochot_interval; 
    370530 
    371531        /* miscellaneous setup regs */ 
     
    374534        u8 sf_tach_to_pwm; 
    375535 
    376         /* <TODO> add members here */ 
     536        /* The two PWM CTL2  registers can read something other than what was 
     537           last written for the OVR_DC field (duty cycle override).  So, we 
     538           save the user-commanded value here. */ 
     539        u8 pwm_override[2]; 
    377540}; 
    378541 
     
    380543static int lm93_attach_adapter(struct i2c_adapter *adapter); 
    381544static int lm93_detect(struct i2c_adapter *adapter, int address, 
    382                        unsigned short flags, int kind); 
     545                unsigned short flags, int kind); 
    383546static int lm93_detach_client(struct i2c_client *client); 
    384547 
     
    397560 
    398561static void lm93_in(struct i2c_client *client, int operation, int ctl_name, 
    399                     int *nrels_mag, long *results); 
     562                int *nrels_mag, long *results); 
    400563static void lm93_temp(struct i2c_client *client, int operation, 
    401                       int ctl_name, int *nrels_mag, long *results); 
     564                int ctl_name, int *nrels_mag, long *results); 
    402565static void lm93_fan(struct i2c_client *client, int operation, 
    403                      int ctl_name, int *nrels_mag, long *results); 
    404 #if 0 
     566                int ctl_name, int *nrels_mag, long *results); 
    405567static void lm93_pwm(struct i2c_client *client, int operation, 
    406                       int ctl_name, int *nrels_mag, long *results); 
    407 #endif 
     568                int ctl_name, int *nrels_mag, long *results); 
     569static void lm93_pwm_freq(struct i2c_client *client, int operation, 
     570                int ctl_name, int *nrels_mag, long *results); 
    408571static void lm93_fan_smart_tach(struct i2c_client *client, int operation, 
    409                      int ctl_name, int *nrels_mag, long *results); 
     572                int ctl_name, int *nrels_mag, long *results); 
    410573static void lm93_vid(struct i2c_client *client, int operation, 
    411                      int ctl_name, int *nrels_mag, long *results); 
     574                int ctl_name, int *nrels_mag, long *results); 
    412575static void lm93_prochot(struct i2c_client *client, int operation, 
    413                      int ctl_name, int *nrels_mag, long *results); 
     576                int ctl_name, int *nrels_mag, long *results); 
    414577static void lm93_prochot_short(struct i2c_client *client, int operation, 
    415                      int ctl_name, int *nrels_mag, long *results); 
    416 #if 0 
     578                int ctl_name, int *nrels_mag, long *results); 
     579static void lm93_prochot_override(struct i2c_client *client, int operation, 
     580                int ctl_name, int *nrels_mag, long *results); 
     581static void lm93_prochot_interval(struct i2c_client *client, int operation, 
     582                int ctl_name, int *nrels_mag, long *results); 
     583static void lm93_vrdhot(struct i2c_client *client, int operation, 
     584                int ctl_name, int *nrels_mag, long *results); 
     585static void lm93_gpio(struct i2c_client *client, int operation, 
     586                int ctl_name, int *nrels_mag, long *results); 
    417587static void lm93_alarms(struct i2c_client *client, int operation, 
    418                         int ctl_name, int *nrels_mag, long *results); 
    419 #endif 
     588                int ctl_name, int *nrels_mag, long *results); 
    420589 
    421590static struct i2c_driver lm93_driver = { 
     
    475644#define LM93_SYSCTL_PWM2        1402 
    476645 
     646/* Hz */ 
     647#define LM93_SYSCTL_PWM1_FREQ   1403 
     648#define LM93_SYSCTL_PWM2_FREQ   1404 
     649 
    477650/* 0 => 0%, 255 => > 99.6% */ 
    478651#define LM93_SYSCTL_PROCHOT1    1501 
     
    482655#define LM93_SYSCTL_PROCHOT_SHORT 1503 
    483656 
    484 /* bitmask of alarms */ 
     657/* 2 boolean enable/disable, 3rd value indicates duty cycle */ 
     658#define LM93_SYSCTL_PROCHOT_OVERRIDE    1504 
     659 
     660/* 2 values, 0-9 */ 
     661#define LM93_SYSCTL_PROCHOT_INTERVAL    1505 
     662 
     663/* GPIO input (bitmask) */ 
     664#define LM93_SYSCTL_GPIO        1601 
     665 
     666/* #VRDHOT input (boolean) */ 
     667#define LM93_SYSCTL_VRDHOT1     1701 
     668#define LM93_SYSCTL_VRDHOT2     1702 
     669 
     670/* alarms (bitmask) */ 
    485671#define LM93_SYSCTL_ALARMS      2001    /* bitvector */ 
    486672 
    487 /* 
    488    <TODO> alarm bitmask definitions 
    489  
    490    This is what would happen if you treated the entire 8 bytes of host 
    491    error status registers as a single big-endian integer.  Trouble is, 
    492    the handler i2c_proc_real() only does 32-bit values.  What to do? 
     673/* alarm bitmask definitions 
     674   The LM93 has nearly 64 bits of error status... I've pared that down to 
     675   what I think is a useful subset in order to fit it into 32 bits. 
     676 
     677   Especially note that the #VRD_HOT alarms are missing because we provide 
     678   that information as values in another /proc file. 
     679 
     680   If libsensors is extended to support 64 bit values, this could be revisited. 
    493681*/ 
    494 #define LM93_ALARM_FAN1         0x0000000000000001ull 
    495 #define LM93_ALARM_FAN2         0x0000000000000002ull 
    496 #define LM93_ALARM_FAN3         0x0000000000000004ull 
    497 #define LM93_ALARM_FAN4         0x0000000000000008ull 
    498 #define LM93_ALARM_PH2_ERR      0x0000000000800000ull 
    499 #define LM93_ALARM_PH1_ERR      0x0000000080000000ull 
    500 #define LM93_ALARM_SCSI1_ERR    0x0000000400000000ull 
    501 #define LM93_ALARM_SCSI2_ERR    0x0000000800000000ull 
    502 #define LM93_ALARM_DVDDP1_ERR   0x0000001000000000ull 
    503 #define LM93_ALARM_DVDDP2_ERR   0x0000002000000000ull 
    504 #define LM93_ALARM_D1_ERR       0x0000004000000000ull 
    505 #define LM93_ALARM_D2_ERR       0x0000008000000000ull 
    506 #define LM93_ALARM_IN1          0x0000010000000000ull 
    507 #define LM93_ALARM_IN2          0x0000020000000000ull 
    508 #define LM93_ALARM_IN3          0x0000040000000000ull 
    509 #define LM93_ALARM_IN4          0x0000080000000000ull 
    510 #define LM93_ALARM_IN5          0x0000100000000000ull 
    511 #define LM93_ALARM_IN6          0x0000200000000000ull 
    512 #define LM93_ALARM_IN7          0x0000400000000000ull 
    513 #define LM93_ALARM_IN8          0x0000800000000000ull 
    514 #define LM93_ALARM_IN9          0x0001000000000000ull 
    515 #define LM93_ALARM_IN10         0x0002000000000000ull 
    516 #define LM93_ALARM_IN11         0x0004000000000000ull 
    517 #define LM93_ALARM_IN12         0x0008000000000000ull 
    518 #define LM93_ALARM_IN13         0x0010000000000000ull 
    519 #define LM93_ALARM_IN14         0x0020000000000000ull 
    520 #define LM93_ALARM_IN15         0x0040000000000000ull 
    521 #define LM93_ALARM_IN16         0x0080000000000000ull 
    522 #define LM93_ALARM_TEMP1        0x0100000000000000ull 
    523 #define LM93_ALARM_TEMP2        0x0200000000000000ull 
    524 #define LM93_ALARM_TEMP3        0x0400000000000000ull 
    525 #define LM93_ALARM_VRD1_ERR     0x1000000000000000ull 
    526 #define LM93_ALARM_VRD2_ERR     0x2000000000000000ull 
    527  
     682#define LM93_ALARM_IN1          0x00000001 
     683#define LM93_ALARM_IN2          0x00000002 
     684#define LM93_ALARM_IN3          0x00000004 
     685#define LM93_ALARM_IN4          0x00000008 
     686#define LM93_ALARM_IN5          0x00000010 
     687#define LM93_ALARM_IN6          0x00000020 
     688#define LM93_ALARM_IN7          0x00000040 
     689#define LM93_ALARM_IN8          0x00000080 
     690#define LM93_ALARM_IN9          0x00000100 
     691#define LM93_ALARM_IN10         0x00000200 
     692#define LM93_ALARM_IN11         0x00000400 
     693#define LM93_ALARM_IN12         0x00000800 
     694#define LM93_ALARM_IN13         0x00001000 
     695#define LM93_ALARM_IN14         0x00002000 
     696#define LM93_ALARM_IN15         0x00004000 
     697#define LM93_ALARM_IN16         0x00008000 
     698#define LM93_ALARM_FAN1         0x00010000 
     699#define LM93_ALARM_FAN2         0x00020000 
     700#define LM93_ALARM_FAN3         0x00040000 
     701#define LM93_ALARM_FAN4         0x00080000 
     702#define LM93_ALARM_PH1_ERR      0x00100000 
     703#define LM93_ALARM_PH2_ERR      0x00200000 
     704#define LM93_ALARM_SCSI1_ERR    0x00400000 
     705#define LM93_ALARM_SCSI2_ERR    0x00800000 
     706#define LM93_ALARM_DVDDP1_ERR   0x01000000 
     707#define LM93_ALARM_DVDDP2_ERR   0x02000000 
     708#define LM93_ALARM_D1_ERR       0x04000000 
     709#define LM93_ALARM_D2_ERR       0x08000000 
     710#define LM93_ALARM_TEMP1        0x10000000 
     711#define LM93_ALARM_TEMP2        0x20000000 
     712#define LM93_ALARM_TEMP3        0x40000000 
    528713 
    529714/* -- SENSORS SYSCTL END -- */ 
     
    541726#define LM93_SYSCTL_PWM(nr)  {LM93_SYSCTL_PWM##nr, "pwm" #nr, NULL, 0, \ 
    542727        0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &lm93_pwm} 
     728#define LM93_SYSCTL_PWM_FREQ(nr)  {LM93_SYSCTL_PWM##nr##_FREQ, \ 
     729        "pwm" #nr "_freq", NULL, 0, 0644, NULL, &i2c_proc_real, \ 
     730        &i2c_sysctl_real, NULL, &lm93_pwm_freq} 
    543731#define LM93_SYSCTL_FAN(nr)  {LM93_SYSCTL_FAN##nr, "fan" #nr, NULL, 0, \ 
    544732        0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &lm93_fan} 
     
    547735#define LM93_SYSCTL_PROCHOT(nr) {LM93_SYSCTL_PROCHOT##nr, "prochot" #nr, NULL, \ 
    548736        0, 0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &lm93_prochot} 
     737#define LM93_SYSCTL_VRDHOT(nr) {LM93_SYSCTL_VRDHOT##nr, "vrdhot" #nr, NULL, \ 
     738        0, 0444, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &lm93_vrdhot} 
    549739#define LM93_SYSCTL_FAN_SMART_TACH(nr) {LM93_SYSCTL_FAN##nr##_SMART_TACH, \ 
    550740        "fan" #nr "_smart_tach", NULL, 0, 0644, NULL, &i2c_proc_real, \ 
     
    582772        LM93_SYSCTL_FAN_SMART_TACH(4), 
    583773 
    584 #if 0 
    585774        LM93_SYSCTL_PWM(1), 
    586775        LM93_SYSCTL_PWM(2), 
    587 #endif 
     776 
     777        LM93_SYSCTL_PWM_FREQ(1), 
     778        LM93_SYSCTL_PWM_FREQ(2), 
    588779 
    589780        LM93_SYSCTL_VID(1), 
     
    595786        {LM93_SYSCTL_PROCHOT_SHORT, "prochot_short", NULL, 0, 0644, NULL, 
    596787         &i2c_proc_real, &i2c_sysctl_real, NULL, &lm93_prochot_short}, 
    597 #if 0 
     788 
     789        {LM93_SYSCTL_PROCHOT_OVERRIDE, "prochot_override", NULL, 0, 0644, NULL, 
     790         &i2c_proc_real, &i2c_sysctl_real, NULL, &lm93_prochot_override}, 
     791 
     792        {LM93_SYSCTL_PROCHOT_INTERVAL, "prochot_interval", NULL, 0, 0644, NULL, 
     793         &i2c_proc_real, &i2c_sysctl_real, NULL, &lm93_prochot_interval}, 
     794 
     795        LM93_SYSCTL_VRDHOT(1), 
     796        LM93_SYSCTL_VRDHOT(2), 
     797 
     798        {LM93_SYSCTL_GPIO, "gpio", NULL, 0, 0444, NULL, 
     799         &i2c_proc_real, &i2c_sysctl_real, NULL, &lm93_gpio}, 
     800 
    598801        {LM93_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, 
    599802         &i2c_sysctl_real, NULL, &lm93_alarms}, 
    600 #endif 
    601803 
    602804        {0} 
     
    9251127                                LM93_REG_VCCP_LIMIT_OFF(i)); 
    9261128 
     1129        /* GPIO input state */ 
     1130        data->gpi = lm93_read_byte(client, LM93_REG_GPI); 
     1131 
     1132        /* #PROCHOT override state */ 
     1133        data->prochot_override = lm93_read_byte(client, 
     1134                        LM93_REG_PROCHOT_OVERRIDE); 
     1135 
     1136        /* #PROCHOT intervals */ 
     1137        data->prochot_interval = lm93_read_byte(client, 
     1138                        LM93_REG_PROCHOT_INTERVAL); 
     1139 
    9271140        /* misc setup registers */ 
    9281141        data->sfc1 = lm93_read_byte(client, LM93_REG_SFC1); 
     
    9521165        lm93_read_block(client, 8, (u8 *)(data->block8)); 
    9531166 
    954         /* <TODO> add code here */ 
     1167        /* pmw control registers */ 
     1168        lm93_read_block(client, 9, (u8 *)(data->block9)); 
    9551169 
    9561170        lm93_update_client_common(data, client); 
     
    9611175                struct i2c_client *client) 
    9621176{ 
    963         int i; 
     1177        int i,j; 
    9641178 
    9651179        pr_debug("lm93.o: starting device update (block data disabled)\n"); 
     
    9961210                        lm93_read_word(client, LM93_REG_FAN_MIN(i)); 
    9971211        } 
    998          
    999         /* <TODO> add code here */ 
     1212 
     1213        /* pwm control registers */ 
     1214        for (i = 0; i < 2; i++) { 
     1215                for (j = 0; j < 4; j++) { 
     1216                        data->block9[i][j] = 
     1217                                lm93_read_word(client, LM93_REG_PWM_CTL(i,j)); 
     1218                } 
     1219        } 
    10001220 
    10011221        lm93_update_client_common(data, client); 
     
    11791399                       T4    T3    T2    T1 
    11801400*/ 
     1401 
     1402/* helper function - must grab data->update_lock before calling 
     1403   fan is 0-3, indicating fan1-fan4 */ 
     1404static void lm93_write_fan_smart_tach(struct i2c_client *client, 
     1405        struct lm93_data *data, int fan, long value) 
     1406{ 
     1407        /* insert the new mapping and write it out */ 
     1408        data->sf_tach_to_pwm = lm93_read_byte(client, LM93_REG_SF_TACH_TO_PWM); 
     1409        data->sf_tach_to_pwm &= ~0x3 << fan * 2; 
     1410        data->sf_tach_to_pwm |= value << fan * 2; 
     1411        lm93_write_byte(client, LM93_REG_SF_TACH_TO_PWM, data->sf_tach_to_pwm); 
     1412 
     1413        /* insert the enable bit and write it out */ 
     1414        data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); 
     1415        if (value) 
     1416                data->sfc2 |= 1 << fan; 
     1417        else 
     1418                data->sfc2 &= ~1 << fan; 
     1419        lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); 
     1420} 
     1421 
     1422/* helper function - must grab data->update_lock before calling 
     1423   pwm is 0-1, indicating pwm1-pwm2 
     1424   this disables smart tach for all tach channels bound to the given pwm */ 
     1425static void lm93_disable_fan_smart_tach(struct i2c_client *client, 
     1426        struct lm93_data *data, int pwm) 
     1427{ 
     1428        int mapping = lm93_read_byte(client, LM93_REG_SF_TACH_TO_PWM); 
     1429        int mask; 
     1430 
     1431        /* collapse the mapping into a mask of enable bits */ 
     1432        mapping = (mapping >> pwm) & 0x55; 
     1433        mask = mapping & 0x01; 
     1434        mask |= (mapping & 0x04) >> 1; 
     1435        mask |= (mapping & 0x10) >> 2; 
     1436        mask |= (mapping & 0x40) >> 3; 
     1437 
     1438        /* disable smart tach according to the mask */ 
     1439        data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); 
     1440        data->sfc2 &= ~mask; 
     1441        lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); 
     1442} 
     1443 
    11811444void lm93_fan_smart_tach(struct i2c_client *client, int operation, int ctl_name, 
    11821445        int *nrels_mag, long *results) 
     
    12111474                        if (0 <= results[0] && results[0] <= 2) { 
    12121475 
    1213                                 /* insert the new mapping and write it out */ 
    1214                                 data->sf_tach_to_pwm = lm93_read_byte(client, 
    1215                                         LM93_REG_SF_TACH_TO_PWM); 
    1216                                 data->sf_tach_to_pwm &= ~0x3 << nr * 2; 
    1217                                 data->sf_tach_to_pwm |= results[0] << nr * 2; 
    1218                                 lm93_write_byte(client, LM93_REG_SF_TACH_TO_PWM, 
    1219                                         data->sf_tach_to_pwm); 
    1220  
    1221                                 /* insert the enable bit and write it out */ 
    1222                                 data->sfc2 = lm93_read_byte(client, 
    1223                                         LM93_REG_SFC2); 
    1224                                 if (results[0]) 
    1225                                         data->sfc2 |= 1 << nr; 
    1226                                 else 
    1227                                         data->sfc2 &= ~1 << nr; 
    1228                                 lm93_write_byte(client, LM93_REG_SFC2, 
    1229                                         data->sfc2); 
     1476                                /* can't enable if pwm freq is 22.5KHz */ 
     1477                                if (results[0]) { 
     1478                                        u8 ctl4 = lm93_read_byte(client, 
     1479                                                LM93_REG_PWM_CTL(results[0]-1, 
     1480                                                LM93_PWM_CTL4)); 
     1481                                        if ((ctl4 & 0x07) == 0) 
     1482                                                results[0] = 0; 
     1483                                } 
     1484 
     1485                                lm93_write_fan_smart_tach(client, data, nr, 
     1486                                                results[0]); 
    12301487                        } 
    1231  
    12321488                        up(&data->update_lock); 
    12331489                } 
     
    12901546} 
    12911547 
    1292 #if 0 
    1293 void lm78_alarms(struct i2c_client *client, int operation, int ctl_name, 
    1294                  int *nrels_mag, long *results) 
    1295 { 
    1296         struct lm78_data *data = client->data; 
     1548void lm93_prochot_override(struct i2c_client *client, int operation, 
     1549        int ctl_name, int *nrels_mag, long *results) 
     1550{ 
     1551        struct lm93_data *data = client->data; 
     1552 
     1553        if (ctl_name != LM93_SYSCTL_PROCHOT_OVERRIDE) 
     1554                return; /* ERROR */ 
     1555 
    12971556        if (operation == SENSORS_PROC_REAL_INFO) 
    12981557                *nrels_mag = 0; 
    12991558        else if (operation == SENSORS_PROC_REAL_READ) { 
    1300                 lm78_update_client(client); 
    1301                 results[0] = ALARMS_FROM_REG(data->alarms); 
     1559                lm93_update_client(client); 
     1560                results[0] = (data->prochot_override & 0x80) ? 1 : 0; 
     1561                results[1] = (data->prochot_override & 0x40) ? 1 : 0; 
     1562                results[2] = data->prochot_override & 0x0f; 
     1563                *nrels_mag = 3; 
     1564        } else if (operation == SENSORS_PROC_REAL_WRITE) { 
     1565 
     1566                /* grab old values */ 
     1567                int force2 = (data->prochot_override & 0x40) ? 1 : 0; 
     1568                int prochot = data->prochot_override & 0x0f; 
     1569 
     1570                down(&data->update_lock); 
     1571                if (*nrels_mag >= 3) { 
     1572                        data->prochot_override = LM93_PROCHOT_OVERRIDE_TO_REG( 
     1573                                results[0], results[1], results[2]); 
     1574                } 
     1575                if (*nrels_mag == 2) { 
     1576                        data->prochot_override = LM93_PROCHOT_OVERRIDE_TO_REG( 
     1577                                results[0], results[1], prochot); 
     1578                } 
     1579                if (*nrels_mag == 1) { 
     1580                        data->prochot_override = LM93_PROCHOT_OVERRIDE_TO_REG( 
     1581                                results[0], force2, prochot); 
     1582                } 
     1583                if (*nrels_mag >= 1) { 
     1584                        lm93_write_byte(client, LM93_REG_PROCHOT_OVERRIDE, 
     1585                                data->prochot_override); 
     1586                } 
     1587                up(&data->update_lock); 
     1588        } 
     1589} 
     1590 
     1591void lm93_prochot_interval(struct i2c_client *client, int operation, 
     1592        int ctl_name, int *nrels_mag, long *results) 
     1593{ 
     1594        struct lm93_data *data = client->data; 
     1595 
     1596        if (ctl_name != LM93_SYSCTL_PROCHOT_INTERVAL) 
     1597                return; /* ERROR */ 
     1598 
     1599        if (operation == SENSORS_PROC_REAL_INFO) 
     1600                *nrels_mag = 2; 
     1601        else if (operation == SENSORS_PROC_REAL_READ) { 
     1602                lm93_update_client(client); 
     1603                results[0] = LM93_INTERVAL_FROM_REG( 
     1604                        data->prochot_interval & 0x0f); 
     1605                results[1] = LM93_INTERVAL_FROM_REG( 
     1606                        (data->prochot_interval & 0xf0) >> 4); 
     1607                *nrels_mag = 2; 
     1608        } else if (operation == SENSORS_PROC_REAL_WRITE) { 
     1609                down(&data->update_lock); 
     1610                if (*nrels_mag >= 2) { 
     1611                        results[1] = SENSORS_LIMIT(results[1], 0, 9); 
     1612                        data->prochot_interval = 
     1613                                (LM93_INTERVAL_TO_REG(results[1] << 4)) | 
     1614                                (data->prochot_interval & 0x0f); 
     1615                } 
     1616                if (*nrels_mag >= 1) { 
     1617                        results[0] = SENSORS_LIMIT(results[0], 0, 9); 
     1618                        data->prochot_interval = 
     1619                                (data->prochot_interval & 0xf0) | 
     1620                                LM93_INTERVAL_TO_REG(results[0]); 
     1621                        lm93_write_byte(client, LM93_REG_PROCHOT_INTERVAL, 
     1622                                data->prochot_interval); 
     1623                } 
     1624                up(&data->update_lock); 
     1625        } 
     1626} 
     1627 
     1628void lm93_vrdhot(struct i2c_client *client, int operation, int ctl_name, 
     1629        int *nrels_mag, long *results) 
     1630{ 
     1631        struct lm93_data *data = client->data; 
     1632        int nr = ctl_name - LM93_SYSCTL_VRDHOT1; 
     1633 
     1634        if (0 > nr || nr > 1) 
     1635                return; /* ERROR */ 
     1636 
     1637        if (operation == SENSORS_PROC_REAL_INFO) 
     1638                *nrels_mag = 0; 
     1639        else if (operation == SENSORS_PROC_REAL_READ) { 
     1640                lm93_update_client(client); 
     1641                results[0] = data->block1.host_status_1 & (1 << (nr+4)) ? 1 : 0; 
    13021642                *nrels_mag = 1; 
    13031643        } 
    13041644} 
    13051645 
    1306 #endif 
     1646void lm93_gpio(struct i2c_client *client, int operation, int ctl_name, 
     1647        int *nrels_mag, long *results) 
     1648{ 
     1649        struct lm93_data *data = client->data; 
     1650 
     1651        if (ctl_name != LM93_SYSCTL_GPIO) 
     1652                return; /* ERROR */ 
     1653 
     1654        if (operation == SENSORS_PROC_REAL_INFO) 
     1655                *nrels_mag = 0; 
     1656        else if (operation == SENSORS_PROC_REAL_READ) { 
     1657                lm93_update_client(client); 
     1658                results[0] = LM93_GPI_FROM_REG(data->gpi); 
     1659                *nrels_mag = 1; 
     1660        } 
     1661} 
     1662 
     1663void lm93_pwm(struct i2c_client *client, int operation, int ctl_name, 
     1664        int *nrels_mag, long *results) 
     1665{ 
     1666        struct lm93_data *data = client->data; 
     1667        int nr = ctl_name - LM93_SYSCTL_PWM1; 
     1668        u8 ctl2, ctl4; 
     1669 
     1670        if (0 > nr || nr > 1) 
     1671                return; /* ERROR */ 
     1672 
     1673        if (operation == SENSORS_PROC_REAL_INFO) 
     1674                *nrels_mag = 0; 
     1675        else if (operation == SENSORS_PROC_REAL_READ) { 
     1676                lm93_update_client(client); 
     1677                ctl2 = data->block9[nr][LM93_PWM_CTL2]; 
     1678                ctl4 = data->block9[nr][LM93_PWM_CTL4]; 
     1679                results[1] = (ctl2 & 0x01) ? 1 : 0; 
     1680                if (results[1]) /* show user commanded value if enabled */ 
     1681                        results[0] = data->pwm_override[nr]; 
     1682                else /* show present h/w value if manual pwm disabled */ 
     1683                        results[0] = LM93_PWM_FROM_REG(ctl2, (ctl4 & 0x07) ? 
     1684                                LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ); 
     1685                *nrels_mag = 2; 
     1686        } 
     1687        else if (operation == SENSORS_PROC_REAL_WRITE) { 
     1688                if (*nrels_mag >= 1) { 
     1689                        down(&data->update_lock); 
     1690                        ctl2 = lm93_read_byte( 
     1691                                client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2)); 
     1692                        ctl4 = lm93_read_byte( 
     1693                                client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); 
     1694                        ctl2 = (ctl2 & 0x0f) |  
     1695                                LM93_PWM_TO_REG(results[0], (ctl4 & 0x07) ? 
     1696                                        LM93_PWM_MAP_LO_FREQ : 
     1697                                        LM93_PWM_MAP_HI_FREQ); 
     1698                        if (*nrels_mag >= 2) { 
     1699                                if (results[1]) 
     1700                                        ctl2 |= 0x01; 
     1701                                else 
     1702                                        ctl2 &= ~0x01; 
     1703                        } 
     1704                        /* save user commanded value */ 
     1705                        data->pwm_override[nr] = 
     1706                                LM93_PWM_FROM_REG(ctl2, (ctl4 & 0x07) ? 
     1707                                        LM93_PWM_MAP_LO_FREQ : 
     1708                                        LM93_PWM_MAP_HI_FREQ); 
     1709                        lm93_write_byte(client, 
     1710                                LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2), ctl2); 
     1711                        up(&data->update_lock); 
     1712                } 
     1713        } 
     1714} 
     1715 
     1716void lm93_pwm_freq(struct i2c_client *client, int operation, int ctl_name, 
     1717        int *nrels_mag, long *results) 
     1718{ 
     1719        struct lm93_data *data = client->data; 
     1720        int nr = ctl_name - LM93_SYSCTL_PWM1_FREQ; 
     1721        u8 ctl4; 
     1722 
     1723        if (0 > nr || nr > 1) 
     1724                return; /* ERROR */ 
     1725 
     1726        if (operation == SENSORS_PROC_REAL_INFO) 
     1727                *nrels_mag = 0; 
     1728        else if (operation == SENSORS_PROC_REAL_READ) { 
     1729                lm93_update_client(client); 
     1730                ctl4 = data->block9[nr][LM93_PWM_CTL4]; 
     1731                results[0] = LM93_PWM_FREQ_FROM_REG(ctl4); 
     1732                *nrels_mag = 1; 
     1733        } 
     1734        else if (operation == SENSORS_PROC_REAL_WRITE) { 
     1735                if (*nrels_mag >= 1) { 
     1736                        down(&data->update_lock); 
     1737                        ctl4 = lm93_read_byte( client, 
     1738                                LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); 
     1739                        ctl4 = (ctl4 & 0xf8) | LM93_PWM_FREQ_TO_REG(results[0]); 
     1740                        data->block9[nr][LM93_PWM_CTL4] = ctl4; 
     1741 
     1742                        /* ctl4 == 0 -> 22.5KHz -> disable smart tach */ 
     1743                        if (!ctl4) 
     1744                                lm93_disable_fan_smart_tach(client, data, nr); 
     1745 
     1746                        lm93_write_byte(client, 
     1747                                LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4), ctl4); 
     1748                        up(&data->update_lock); 
     1749                } 
     1750        } 
     1751} 
     1752 
     1753void lm93_alarms(struct i2c_client *client, int operation, int ctl_name, 
     1754        int *nrels_mag, long *results) 
     1755{ 
     1756        struct lm93_data *data = client->data; 
     1757        if (operation == SENSORS_PROC_REAL_INFO) 
     1758                *nrels_mag = 0; 
     1759        else if (operation == SENSORS_PROC_REAL_READ) { 
     1760                lm93_update_client(client); 
     1761                results[0] = LM93_ALARMS_FROM_REG(data->block1); 
     1762                *nrels_mag = 1; 
     1763        } 
     1764} 
    13071765 
    13081766static int __init lm93_init(void)