root/lm-sensors/trunk/kernel/chips/maxilife.c @ 499

Revision 499, 26.0 KB (checked in by kmalkki, 15 years ago)

(Kyösti)

  • renamed every smbus_* access to i2c_smbus_*
  • everything in lm_sensors2/kernel/* compiles nicely :)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    maxilife.c - Part of lm_sensors, Linux kernel modules for hardware
3                 monitoring
4    Copyright (c) 1999  Fons Rademakers <Fons.Rademakers@cern.ch>
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21/* The is the driver for the HP MaxiLife Health monitoring system
22   as used in the line of HP Kayak Workstation PC's.
23   
24   The driver supports the following MaxiLife firmware versions:
25   
26   0) HP KAYAK XU/XAs (Dual Pentium II Slot 1, Deschutes/Klamath)
27   1) HP KAYAK XU (Dual Xeon [Slot 2] 400/450 Mhz)
28   2) HP KAYAK XA (Pentium II Slot 1, monoprocessor)
29   
30   Currently firmware auto detection is not implemented. To use the
31   driver load it with the correct option for you Kayak. For example:
32   
33   insmod maxilife.o maxi_version=0 | 1 | 2
34   
35   maxi_version=0 is the default
36*/
37
38static const char *version_str = "1.00 25/2/99 Fons Rademakers";
39
40
41#include <linux/module.h>
42#include <linux/malloc.h>
43#include <linux/proc_fs.h>
44#include <linux/ioport.h>
45#include <linux/sysctl.h>
46#include <asm/errno.h>
47#include <asm/io.h>
48#include <linux/types.h>
49#include <linux/i2c.h>
50#include "version.h"
51#include "sensors.h"
52#include "compat.h"
53
54
55#undef AUTODETECT          /* try to autodetect MaxiLife version */
56#define NOWRITE             /* don't allow writing to MaxiLife registers */
57
58
59/* The MaxiLife registers */
60#define MAXI_REG_TEMP(nr)      (0x60 + (nr))
61
62#define MAXI_REG_FAN(nr)       (0x65 + (nr))
63#define MAXI_REG_FAN_MIN(nr)   ((nr)==0 ? 0xb3 : (nr)==1 ? 0xb3 : 0xab)
64#define MAXI_REG_FAN_MINAS(nr) ((nr)==0 ? 0xb3 : (nr)==1 ? 0xab : 0xb3)
65#define MAXI_REG_FAN_SPEED(nr) ((nr)==0 ? 0xe4 : (nr)==1 ? 0xe5 : 0xe9)
66
67#define MAXI_REG_PLL           0xb9
68#define MAXI_REG_PLL_MIN       0xba
69#define MAXI_REG_PLL_MAX       0xbb
70
71#define MAXI_REG_VID(nr)       ((nr)==0 ? 0xd1 : (nr)==1 ? 0xd9 : \
72                                (nr)==2 ? 0xd4 : 0xc5)
73#define MAXI_REG_VID_MIN(nr)   MAXI_REG_VID(nr)+1
74#define MAXI_REG_VID_MAX(nr)   MAXI_REG_VID(nr)+2
75
76#define MAXI_REG_DIAG_RT1      0x2c
77#define MAXI_REG_DIAG_RT2      0x2d
78
79#define MAXI_REG_BIOS_CTRL     0x2a
80#define MAXI_REG_LED_STATE     0x96
81
82/* Conversions. Rounding and limit checking is only done on the TO_REG
83   variants. Note that you should be a bit careful with which arguments
84   these macros are called: arguments may be evaluated more than once.
85   Fixing this is just not worth it. */
86
87                               /* 0xfe: fan off, 0xff: stopped (alarm) */
88                               /* 19531 / val * 60 == 1171860 / val */
89#define FAN_FROM_REG(val)      ((val)==0xfe ? -1 : (val)==0xff ? 0 : \
90                                (val)==0x00 ? -1 : (1171860 / (val)))
91
92extern inline u8 FAN_TO_REG(long rpm)
93{
94  if (rpm == 0)
95    return 255;
96  rpm = SENSORS_LIMIT(rpm,1,1000000);
97  return SENSORS_LIMIT((1171860 + rpm/2) / (rpm),1,254);
98}
99
100#define TEMP_FROM_REG(val)     ((val) * 5)
101#define TEMP_TO_REG(val)       (SENSORS_LIMIT((val+2) / 5),0,0xff)
102#define PLL_FROM_REG(val)      (((val) * 1000) / 32)
103#define PLL_TO_REG(val)        (SENSORS_LIMIT((((val) * 32 + 500) / 1000),\
104                                              0,0xff))
105#define VID_FROM_REG(val)      ((val) ? (((val) * 27390) / 256) + 3208 : 0)
106#define VID_TO_REG(val)        (SENSORS_LIMIT((((val) - 3208) * 256) / 27390, \
107                                              0,255))
108#define ALARMS_FROM_REG(val)   (val)
109
110#ifdef MODULE
111extern int init_module(void);
112extern int cleanup_module(void);
113#endif /* MODULE */
114
115/* The following product codenames apply:
116     Cristal/Geronimo: HP KAYAK XU/XAs
117                       (Dual Pentium II Slot 1, Deschutes/Klamath)
118     Cognac: HP KAYAK XU (Dual Xeon [Slot 2] 400/450 Mhz)
119     Ashaki: HP KAYAK XA (Pentium II Slot 1, monoprocessor) */
120
121enum maxi_type { cristal, cognac, ashaki };
122
123/* For each registered MaxiLife controller, we need to keep some data in
124   memory. That data is pointed to by maxi_list[NR]->data. The structure
125   itself is dynamically allocated, at the same time when a new MaxiLife
126   client is allocated. We assume MaxiLife will only be present on the
127   SMBus and not on the ISA bus. */
128struct maxi_data {
129   struct semaphore lock;
130   int              sysctl_id;
131   enum maxi_type   type;
132
133   struct semaphore update_lock;
134   char             valid;         /* !=0 if following fields are valid */
135   unsigned long    last_updated;  /* In jiffies */
136
137   u8  fan[3];                  /* Register value */
138   u8  fan_min[3];              /* Register value */
139   u8  fan_speed[3];            /* Register value */
140   u8  fan_div[3];              /* Static value */
141   u8  temp[5];                 /* Register value */
142   u8  temp_max[5];             /* Static value */
143   u8  temp_hyst[5];            /* Static value */
144   u8  pll;                     /* Register value */
145   u8  pll_min;                 /* Register value */
146   u8  pll_max;                 /* register value */
147   u8  vid[4];                  /* Register value */
148   u8  vid_min[4];              /* Register value */
149   u8  vid_max[4];              /* Register value */
150   u16 alarms;                  /* Register encoding, combined */
151};
152
153
154static int  maxi_init(void);
155static int  maxi_cleanup(void);
156
157static int  maxi_attach_adapter(struct i2c_adapter *adapter);
158static int  maxi_detect_smbus(struct i2c_adapter *adapter);
159static int  maxi_detach_client(struct i2c_client *client);
160static int  maxi_detach_smbus(struct i2c_client *client);
161static int  maxi_new_client(struct i2c_adapter *adapter,
162                           struct i2c_client *new_client);
163static void maxi_remove_client(struct i2c_client *client);
164static int  maxi_command(struct i2c_client *client, unsigned int cmd, 
165                        void *arg);
166static void maxi_inc_use (struct i2c_client *client);
167static void maxi_dec_use (struct i2c_client *client);
168
169static int  maxi_read_value(struct i2c_client *client, u8 register);
170#ifndef NOWRITE
171static int  maxi_write_value(struct i2c_client *client, u8 register, u8 value);
172#endif
173static void maxi_update_client(struct i2c_client *client);
174static void maxi_init_client(struct i2c_client *client);
175
176static void maxi_fan(struct i2c_client *client, int operation, int ctl_name,
177                     int *nrels_mag, long *results);
178static void maxi_temp(struct i2c_client *client, int operation, int ctl_name,
179                      int *nrels_mag, long *results);
180static void maxi_pll(struct i2c_client *client, int operation, int ctl_name,
181                     int *nrels_mag, long *results);
182static void maxi_vid(struct i2c_client *client, int operation, int ctl_name,
183                     int *nrels_mag, long *results);
184static void maxi_alarms(struct i2c_client *client, int operation, int ctl_name,
185                        int *nrels_mag, long *results);
186
187
188/* I choose here for semi-static MaxiLife allocation. Complete dynamic
189   allocation could also be used; the code needed for this would probably
190   take more memory than the datastructure takes now. */
191#define MAX_MAXI_NR 4
192static struct i2c_client *maxi_list[MAX_MAXI_NR];
193
194/* The driver. I choose to use type i2c_driver, as at is identical to
195   the smbus_driver. */
196static struct i2c_driver maxi_driver = {
197  /* name */            "HP MaxiLife driver",
198  /* id */              I2C_DRIVERID_MAXILIFE,
199  /* flags */           I2C_DF_NOTIFY,
200  /* attach_adapter */  &maxi_attach_adapter,
201  /* detach_client */   &maxi_detach_client,
202  /* command */         &maxi_command,
203  /* inc_use */         &maxi_inc_use,
204  /* dec_use */         &maxi_dec_use
205};
206
207/* Used by maxi_init/cleanup */
208static int maxi_initialized = 0;
209
210/* Default firmware version. Use module option "maxi_version"
211   to set desired version. Auto detect is not yet working */
212static int maxi_version = cristal;
213
214/* The /proc/sys entries */
215/* These files are created for each detected MaxiLife processor.
216   This is just a template; though at first sight, you might think we
217   could use a statically allocated list, we need some way to get back
218   to the parent - which is done through one of the 'extra' fields
219   which are initialized when a new copy is allocated. */
220static ctl_table maxi_dir_table_template[] = {
221   { MAXI_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &sensors_proc_real,
222     &sensors_sysctl_real, NULL, &maxi_fan },
223   { MAXI_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &sensors_proc_real,
224     &sensors_sysctl_real, NULL, &maxi_fan },
225   { MAXI_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &sensors_proc_real,
226     &sensors_sysctl_real, NULL, &maxi_fan },
227   { MAXI_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &sensors_proc_real,
228     &sensors_sysctl_real, NULL, &maxi_temp },
229   { MAXI_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &sensors_proc_real,
230     &sensors_sysctl_real, NULL, &maxi_temp },
231   { MAXI_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &sensors_proc_real,
232     &sensors_sysctl_real, NULL, &maxi_temp },
233   { MAXI_SYSCTL_TEMP4, "temp4", NULL, 0, 0644, NULL, &sensors_proc_real,
234     &sensors_sysctl_real, NULL, &maxi_temp },
235   { MAXI_SYSCTL_TEMP5, "temp5", NULL, 0, 0644, NULL, &sensors_proc_real,
236     &sensors_sysctl_real, NULL, &maxi_temp },
237   { MAXI_SYSCTL_PLL, "pll", NULL, 0, 0644, NULL, &sensors_proc_real,
238     &sensors_sysctl_real, NULL, &maxi_pll },
239   { MAXI_SYSCTL_VID1, "vid1", NULL, 0, 0644, NULL, &sensors_proc_real,
240     &sensors_sysctl_real, NULL, &maxi_vid },
241   { MAXI_SYSCTL_VID2, "vid2", NULL, 0, 0644, NULL, &sensors_proc_real,
242     &sensors_sysctl_real, NULL, &maxi_vid },
243   { MAXI_SYSCTL_VID3, "vid3", NULL, 0, 0644, NULL, &sensors_proc_real,
244     &sensors_sysctl_real, NULL, &maxi_vid },
245   { MAXI_SYSCTL_VID4, "vid4", NULL, 0, 0644, NULL, &sensors_proc_real,
246     &sensors_sysctl_real, NULL, &maxi_vid },
247   { MAXI_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &sensors_proc_real,
248     &sensors_sysctl_real, NULL, &maxi_alarms },
249   { 0 }
250};
251
252/* This function is called when:
253    - maxi_driver is inserted (when this module is loaded), for each
254      available adapter
255    - when a new adapter is inserted (and maxi_driver is still present) */
256int maxi_attach_adapter(struct i2c_adapter *adapter)
257{
258   return maxi_detect_smbus(adapter);
259}
260
261/* This function is called whenever a client should be removed:
262    - maxi_driver is removed (when this module is unloaded)
263    - when an adapter is removed which has a maxi client (and maxi_driver
264      is still present). */
265int maxi_detach_client(struct i2c_client *client)
266{
267   return maxi_detach_smbus(client);
268}
269
270int maxi_detect_smbus(struct i2c_adapter *adapter)
271{
272#ifdef AUTODETECT
273   u8  biosctl;
274#endif
275   int address, err;
276   struct i2c_client *new_client;
277   enum maxi_type type;
278   const char *type_name, *client_name;
279
280   /* OK, this is no detection. I know. It will do for now, though. */
281   err = 0;
282   for (address = 0x10; (! err) && (address <= 0x14); address++) {
283
284      /* Later on, we will keep a list of registered addresses for each
285         adapter, and check whether they are used here */
286
287      if (i2c_smbus_read_byte_data(adapter, address, MAXI_REG_LED_STATE) < 0) 
288         continue;
289
290#ifdef AUTODETECT
291      /* The right way to get the platform info is to read the firmware
292         revision from serial EEPROM (addr=0x54), at offset 0x0045.
293         This is a string as:
294           "CG 00.04" -> Cristal [XU] / Geronimo [XAs]
295           "CO 00.03" -> Cognac [XU]
296           "AS 00.01" -> Ashaki [XA] */
297      biosctl = i2c_smbus_read_byte_data(adapter, address, MAXI_REG_BIOS_CTRL);
298      i2c_smbus_write_byte_data(adapter, address, MAXI_REG_BIOS_CTRL, biosctl|4);
299      err = eeprom_read_byte_data(adapter, 0x54, 0x45);
300      i2c_smbus_write_byte_data(adapter, address, MAXI_REG_BIOS_CTRL, biosctl);
301#endif
302
303      if (maxi_version == cristal) {
304         type = cristal;
305         type_name = "maxilife-cg";
306         client_name = "HP MaxiLife Rev CG 00.04";
307         printk("maxilife: HP KAYAK XU/XAs (Dual Pentium II Slot 1)\n");
308      } else if (maxi_version == cognac) {
309         type = cognac;
310         type_name = "maxilife-co";
311         client_name = "HP MaxiLife Rev CO 00.03";
312         printk("maxilife: HP KAYAK XU (Dual Xeon Slot 2 400/450 Mhz)\n");
313      } else if (maxi_version == ashaki) {
314         type = ashaki;
315         type_name = "maxilife-as";
316         client_name = "HP MaxiLife Rev AS 00.01";
317         printk("maxilife: HP KAYAK XA (Pentium II Slot 1, monoprocessor)\n");
318      } else {
319#if AUTODETECT
320         printk("maxilife: Warning: probed non-maxilife chip?!? (%x)\n", err);
321#else
322         printk("maxilife: Error: specified wrong maxi_version (%d)\n",
323                maxi_version);
324#endif
325         continue;
326      }
327
328      /* Allocate space for a new client structure. To counter memory
329         fragmentation somewhat, we only do one kmalloc. */
330      if (! (new_client = kmalloc(sizeof(struct i2c_client) + 
331                                  sizeof(struct maxi_data),
332                                  GFP_KERNEL))) {
333         err = -ENOMEM;
334         continue;
335      }
336
337      /* Fill the new client structure with data */
338      new_client->data = (struct maxi_data *) (new_client + 1);
339      new_client->addr = address;
340      strcpy(new_client->name, client_name);
341      ((struct maxi_data *) (new_client->data))->type = type;
342      if ((err = maxi_new_client(adapter, new_client)))
343         goto ERROR2;
344
345      /* Tell i2c-core a new client has arrived */
346      if ((err = i2c_attach_client(new_client))) 
347         goto ERROR3;
348
349      /* Register a new directory entry with module sensors */
350      if ((err = sensors_register_entry(new_client, type_name,
351                                        maxi_dir_table_template)) < 0)
352         goto ERROR4;
353      ((struct maxi_data *) (new_client->data))->sysctl_id = err;
354      err = 0;
355
356      /* Initialize the MaxiLife chip */
357      maxi_init_client(new_client);
358      continue;
359
360      /* OK, this is not exactly good programming practice, usually.
361         But it is very code-efficient in this case. */
362ERROR4:
363      i2c_detach_client(new_client);
364ERROR3:
365      maxi_remove_client((struct i2c_client *) new_client);
366ERROR2:
367      kfree(new_client);
368   }
369   return err;
370}
371
372int maxi_detach_smbus(struct i2c_client *client)
373{
374   int err,i;
375   for (i = 0; i < MAX_MAXI_NR; i++)
376      if (client == maxi_list[i])
377         break;
378   if ((i == MAX_MAXI_NR)) {
379      printk("maxilife: Client to detach not found.\n");
380      return -ENOENT;
381   }
382
383   sensors_deregister_entry(((struct maxi_data *)(client->data))->sysctl_id);
384
385   if ((err = i2c_detach_client(client))) {
386      printk("maxilife: Client deregistration failed, client not detached.\n");
387      return err;
388   }
389   maxi_remove_client(client);
390   kfree(client);
391   return 0;
392}
393
394/* Find a free slot, and initialize most of the fields */
395int maxi_new_client(struct i2c_adapter *adapter,
396                    struct i2c_client *new_client)
397{
398   int i;
399   struct maxi_data *data;
400
401   /* First, seek out an empty slot */
402   for (i = 0; i < MAX_MAXI_NR; i++)
403      if (!maxi_list[i])
404         break;
405   if (i == MAX_MAXI_NR) {
406      printk("maxilife: No empty slots left, recompile and heighten "
407             "MAX_MAXI_NR!\n");
408      return -ENOMEM;
409   }
410 
411   maxi_list[i] = new_client;
412   new_client->id = i;
413   new_client->adapter = adapter;
414   new_client->driver = &maxi_driver;
415   data = new_client->data;
416   data->valid = 0;
417   init_MUTEX(&data->lock);
418   init_MUTEX(&data->update_lock);
419   return 0;
420}
421
422/* Inverse of maxi_new_client */
423void maxi_remove_client(struct i2c_client *client)
424{
425   int i;
426   for (i = 0; i < MAX_MAXI_NR; i++)
427      if (client == maxi_list[i]) 
428         maxi_list[i] = NULL;
429}
430
431/* No commands defined yet */
432int maxi_command(struct i2c_client *client, unsigned int cmd, void *arg)
433{
434   return 0;
435}
436
437/* Nothing here yet */
438void maxi_inc_use (struct i2c_client *client)
439{
440#ifdef MODULE
441   MOD_INC_USE_COUNT;
442#endif
443}
444
445/* Nothing here yet */
446void maxi_dec_use (struct i2c_client *client)
447{
448#ifdef MODULE
449   MOD_DEC_USE_COUNT;
450#endif
451}
452
453
454/* Read byte from specified register. */
455int maxi_read_value(struct i2c_client *client, u8 reg)
456{
457   return i2c_smbus_read_byte_data(client->adapter, client->addr, reg);
458}
459
460#ifndef NOWRITE
461/* Write byte to specified register. */ 
462int maxi_write_value(struct i2c_client *client, u8 reg, u8 value)
463{
464   return i2c_smbus_write_byte_data(client->adapter, client->addr, reg, value);
465}
466#endif
467
468/* Called when we have found a new MaxiLife. It should set limits, etc. */
469void maxi_init_client(struct i2c_client *client)
470{
471   /* start with default settings */ 
472}
473
474void maxi_update_client(struct i2c_client *client)
475{
476   struct maxi_data *data = client->data;
477   int i;
478
479   down(&data->update_lock);
480
481   if ((jiffies - data->last_updated > HZ+HZ/2 ) ||
482       (jiffies < data->last_updated) || !data->valid) {
483
484#ifdef DEBUG
485      printk("maxilife: Starting MaxiLife update\n");
486#endif
487      for (i = 0; i < 5; i++)
488         data->temp[i] = maxi_read_value(client, MAXI_REG_TEMP(i));
489      switch (data->type) {
490         case cristal:
491            data->temp[0]      = 0;   /* not valid */
492            data->temp_max[0]  = 0;
493            data->temp_hyst[0] = 0;
494            data->temp_max[1]  = 110; /* max PCI slot temp */
495            data->temp_hyst[1] = 100;
496            data->temp_max[2]  = 120; /* max BX chipset temp */
497            data->temp_hyst[2] = 110;
498            data->temp_max[3]  = 100; /* max HDD temp */
499            data->temp_hyst[3] = 90;
500            data->temp_max[4]  = 120; /* max CPU temp */
501            data->temp_hyst[4] = 110;
502            break;
503           
504         case cognac:
505            data->temp_max[0]  = 120; /* max CPU1 temp */
506            data->temp_hyst[0] = 110;
507            data->temp_max[1]  = 110; /* max PCI slot temp */
508            data->temp_hyst[1] = 100;
509            data->temp_max[2]  = 120; /* max CPU2 temp */
510            data->temp_hyst[2] = 110;
511            data->temp_max[3]  = 100; /* max HDD temp */
512            data->temp_hyst[3] = 90;
513            data->temp_max[4]  = 120; /* max reference CPU temp */
514            data->temp_hyst[4] = 110;
515            break;
516           
517         case ashaki:
518            data->temp[0]      = 0;   /* not valid */
519            data->temp_max[0]  = 0;
520            data->temp_hyst[0] = 0;
521            data->temp_max[1]  = 110; /* max PCI slot temp */
522            data->temp_hyst[1] = 100;
523            data->temp[2]      = 0;   /* not valid */
524            data->temp_max[2]  = 0;
525            data->temp_hyst[2] = 0;
526            data->temp_max[3]  = 100; /* max HDD temp */
527            data->temp_hyst[3] = 90;
528            data->temp_max[4]  = 120; /* max CPU temp */
529            data->temp_hyst[4] = 110;
530            break;
531           
532         default:
533            printk("maxilife: Unknown MaxiLife chip\n");
534      }
535
536      for (i = 0; i < 3; i++) {     
537         data->fan[i]       = maxi_read_value(client, MAXI_REG_FAN(i));
538         data->fan_speed[i] = maxi_read_value(client, MAXI_REG_FAN_SPEED(i));
539         data->fan_div[i]   = 4;
540         if (data->type == ashaki)
541            data->fan_min[i] = maxi_read_value(client, MAXI_REG_FAN_MINAS(i));
542         else
543            data->fan_min[i] = maxi_read_value(client, MAXI_REG_FAN_MIN(i));
544      }
545     
546      data->pll     = maxi_read_value(client, MAXI_REG_PLL);
547      data->pll_min = maxi_read_value(client, MAXI_REG_PLL_MIN);
548      data->pll_max = maxi_read_value(client, MAXI_REG_PLL_MAX);
549
550      for (i = 0; i < 4; i++) {
551         data->vid[i]     = maxi_read_value(client, MAXI_REG_VID(i));
552         data->vid_min[i] = maxi_read_value(client, MAXI_REG_VID_MIN(i));
553         data->vid_max[i] = maxi_read_value(client, MAXI_REG_VID_MAX(i));
554      }
555      switch (data->type) {
556         case cristal:
557            data->vid[3]     = 0;   /* no voltage cache L2 */
558            data->vid_min[3] = 0;
559            data->vid_max[3] = 0;
560            break;
561
562         case cognac:
563            break;
564
565         case ashaki:
566            data->vid[1]     = 0;   /* no voltage CPU 2 */
567            data->vid_min[1] = 0;
568            data->vid_max[1] = 0;
569            data->vid[3]     = 0;   /* no voltage cache L2 */
570            data->vid_min[3] = 0;
571            data->vid_max[3] = 0;
572            break;
573
574         default:
575            printk("maxilife: Unknown MaxiLife chip\n");
576      }
577
578      data->alarms = maxi_read_value(client, MAXI_REG_DIAG_RT1) +
579                    (maxi_read_value(client, MAXI_REG_DIAG_RT2) << 8);
580      data->last_updated = jiffies;
581      data->valid = 1;
582   }
583
584   up(&data->update_lock);
585}
586
587/* The next few functions are the call-back functions of the /proc/sys and
588   sysctl files. Which function is used is defined in the ctl_table in
589   the extra1 field.
590   Each function must return the magnitude (power of 10 to divide the data
591   with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must
592   put a maximum of *nrels elements in results reflecting the data of this
593   file, and set *nrels to the number it actually put in it, if operation==
594   SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from
595   results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE.
596   Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
597   large enough (by checking the incoming value of *nrels). This is not very
598   good practice, but as long as you put less than about 5 values in results,
599   you can assume it is large enough. */
600void maxi_fan(struct i2c_client *client, int operation, int ctl_name,
601              int *nrels_mag, long *results)
602{
603   struct maxi_data *data = client->data;
604   int nr = ctl_name - MAXI_SYSCTL_FAN1 + 1;
605
606   if (operation == SENSORS_PROC_REAL_INFO)
607      *nrels_mag = 0;
608   else if (operation == SENSORS_PROC_REAL_READ) {
609      maxi_update_client(client);
610      results[0] = FAN_FROM_REG(data->fan_min[nr-1]);
611      results[1] = data->fan_div[nr-1];
612      results[2] = FAN_FROM_REG(data->fan[nr-1]);
613      *nrels_mag = 3;
614   } else if (operation == SENSORS_PROC_REAL_WRITE) {
615#ifndef NOWRITE
616      if (*nrels_mag >= 1) {
617         data->fan_min[nr-1] = FAN_TO_REG(results[0]);
618         maxi_write_value(client, MAXI_REG_FAN_MIN(nr), data->fan_min[nr-1]);
619      }
620#endif
621   }
622}
623
624void maxi_temp(struct i2c_client *client, int operation, int ctl_name,
625               int *nrels_mag, long *results)
626{
627   struct maxi_data *data = client->data;
628   int nr = ctl_name - MAXI_SYSCTL_TEMP1 + 1;
629
630   if (operation == SENSORS_PROC_REAL_INFO)
631      *nrels_mag = 1;
632   else if (operation == SENSORS_PROC_REAL_READ) {
633      maxi_update_client(client);
634      results[0] = TEMP_FROM_REG(data->temp_max[nr-1]);
635      results[1] = TEMP_FROM_REG(data->temp_hyst[nr-1]);
636      results[2] = TEMP_FROM_REG(data->temp[nr-1]);
637      *nrels_mag = 3;
638   } else if (operation == SENSORS_PROC_REAL_WRITE) {
639      /* temperature range can not be changed */
640   }
641}
642
643void maxi_pll(struct i2c_client *client, int operation, int ctl_name,
644              int *nrels_mag, long *results)
645{
646   struct maxi_data *data = client->data;
647 
648   if (operation == SENSORS_PROC_REAL_INFO)
649      *nrels_mag = 2;
650   else if (operation == SENSORS_PROC_REAL_READ) {
651      maxi_update_client(client);
652      results[0] = PLL_FROM_REG(data->pll_min);
653      results[1] = PLL_FROM_REG(data->pll_max);
654      results[2] = PLL_FROM_REG(data->pll);
655      *nrels_mag = 3;
656   } else if (operation == SENSORS_PROC_REAL_WRITE) {
657#ifndef NOWRITE
658      if (*nrels_mag >= 1) {
659         data->pll_min = PLL_TO_REG(results[0]);
660         maxi_write_value(client, MAXI_REG_PLL_MIN, data->pll_min);
661      }
662      if (*nrels_mag >= 2) {
663         data->pll_max = PLL_TO_REG(results[1]);
664         maxi_write_value(client, MAXI_REG_PLL_MAX, data->pll_max);
665      }
666#endif
667   }
668}
669
670void maxi_vid(struct i2c_client *client, int operation, int ctl_name,
671              int *nrels_mag, long *results)
672{
673   struct maxi_data *data = client->data;
674   int nr = ctl_name - MAXI_SYSCTL_VID1 + 1;
675
676   if (operation == SENSORS_PROC_REAL_INFO)
677      *nrels_mag = 4;
678   else if (operation == SENSORS_PROC_REAL_READ) {
679      maxi_update_client(client);
680      results[0] = VID_FROM_REG(data->vid_min[nr-1]);
681      results[1] = VID_FROM_REG(data->vid_max[nr-1]);
682      results[2] = VID_FROM_REG(data->vid[nr-1]);
683      *nrels_mag = 3;
684   } else if (operation == SENSORS_PROC_REAL_WRITE) {
685#ifndef NOWRITE
686      if (*nrels_mag >= 1) {
687         data->vid_min[nr-1] = VID_TO_REG(results[0]);
688         maxi_write_value(client, MAXI_REG_VID_MIN(nr), data->vid_min[nr-1]);
689      }
690      if (*nrels_mag >= 2) {
691         data->vid_max[nr-1] = VID_TO_REG(results[1]);
692         maxi_write_value(client, MAXI_REG_VID_MAX(nr), data->vid_max[nr-1]);
693      }
694#endif
695   }
696}
697
698void maxi_alarms(struct i2c_client *client, int operation, int ctl_name,
699                 int *nrels_mag, long *results)
700{
701   struct maxi_data *data = client->data;
702 
703   if (operation == SENSORS_PROC_REAL_INFO)
704      *nrels_mag = 0;
705   else if (operation == SENSORS_PROC_REAL_READ) {
706      maxi_update_client(client);
707      results[0] = ALARMS_FROM_REG(data->alarms);
708      *nrels_mag = 1;
709   }
710}
711
712int maxi_init(void)
713{
714   int res;
715
716   printk("maxilife: Version %s (lm_sensors %s (%s))\n", version_str,
717          LM_VERSION, LM_DATE);
718   maxi_initialized = 0;
719
720   if ((res = i2c_add_driver(&maxi_driver))) {
721      printk("maxilife: Driver registration failed, module not inserted.\n");
722      maxi_cleanup();
723      return res;
724   }
725   maxi_initialized++;
726   return 0;
727}
728
729int maxi_cleanup(void)
730{
731   int res;
732
733   if (maxi_initialized >= 1) {
734      if ((res = i2c_del_driver(&maxi_driver))) {
735         printk("maxilife: Driver deregistration failed, module not removed.\n");
736         return res;
737      }
738      maxi_initialized--;
739   }
740   return 0;
741}
742
743
744#ifdef MODULE
745
746MODULE_AUTHOR("Fons Rademakers <Fons.Rademakers@cern.ch>");
747MODULE_DESCRIPTION("HP MaxiLife driver");
748MODULE_PARM(maxi_version, "i");
749MODULE_PARM_DESC(maxi_version, "MaxiLife firmware version");
750
751int init_module(void)
752{
753   return maxi_init();
754}
755
756int cleanup_module(void)
757{
758   return maxi_cleanup();
759}
760
761#endif /* MODULE */
762
763
Note: See TracBrowser for help on using the browser.