Show
Ignore:
Timestamp:
08/13/04 21:29:33 (10 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.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • 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)