root/lm-sensors/trunk/kernel/chips/vt8231.c @ 2867

Revision 2867, 23.7 KB (checked in by khali, 8 years ago)

Drop unused client id.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    vt8231.c - Part of lm_sensors, Linux kernel modules
3                for hardware monitoring
4               
5    Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22/* Supports VIA VT8231 South Bridge embedded sensors */
23
24#include <linux/module.h>
25#include <linux/slab.h>
26#include <linux/ioport.h>
27#include <linux/pci.h>
28#include <linux/i2c.h>
29#include <linux/i2c-proc.h>
30#include <linux/init.h>
31#include <asm/io.h>
32#include "version.h"
33#include "sensors_vid.h"
34
35
36static int force_addr = 0;
37MODULE_PARM(force_addr, "i");
38MODULE_PARM_DESC(force_addr,
39                 "Initialize the base address of the sensors");
40
41static unsigned short normal_i2c[] = { SENSORS_I2C_END };
42static unsigned short normal_i2c_range[] = { SENSORS_I2C_END };
43static unsigned int normal_isa[] = { 0x0000, SENSORS_ISA_END };
44static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
45
46SENSORS_INSMOD_1(vt8231);
47
48#define VIA686A_EXTENT 0x80
49#define VIA686A_BASE_REG 0x70
50#define VIA686A_ENABLE_REG 0x74
51
52/* pwm numbered 1-2 */
53#define VT8231_REG_PWM(nr) (0x5f + (nr))
54#define VT8231_REG_PWM_CTL 0x51
55
56/* The VT8231 registers */
57/* We define the sensors as follows. Somewhat convoluted to minimize
58   changes from via686a.
59        Sensor          Voltage Mode    Temp Mode
60        --------        ------------    ---------
61        Reading 1                       temp3
62        Reading 3                       temp1   not in vt8231
63        UCH1/Reading2   in0             temp2
64        UCH2            in1             temp4
65        UCH3            in2             temp5
66        UCH4            in3             temp6
67        UCH5            in4             temp7
68        3.3V            in5
69        -12V            in6                     not in vt8231
70*/
71
72/* ins numbered 0-6 */
73#define VT8231_REG_IN_MAX(nr) ((nr)==0 ? 0x3d : 0x29 + ((nr) * 2))
74#define VT8231_REG_IN_MIN(nr) ((nr)==0 ? 0x3e : 0x2a + ((nr) * 2))
75#define VT8231_REG_IN(nr)     (0x21 + (nr))
76
77/* fans numbered 1-2 */
78#define VT8231_REG_FAN_MIN(nr) (0x3a + (nr))
79#define VT8231_REG_FAN(nr)     (0x28 + (nr))
80
81static const u8 regtemp[] = { 0x20, 0x21, 0x1f, 0x22, 0x23, 0x24, 0x25 };
82static const u8 regover[] = { 0x39, 0x3d, 0x1d, 0x2b, 0x2d, 0x2f, 0x31 };
83static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e, 0x2c, 0x2e, 0x30, 0x32 };
84
85/* temps numbered 1-7 */
86#define VT8231_REG_TEMP(nr)             (regtemp[(nr) - 1])
87#define VT8231_REG_TEMP_OVER(nr)        (regover[(nr) - 1])
88#define VT8231_REG_TEMP_HYST(nr)        (reghyst[(nr) - 1])
89#define VT8231_REG_TEMP_LOW3    0x4b    /* bits 7-6 */
90#define VT8231_REG_TEMP_LOW2    0x49    /* bits 5-4 */
91#define VT8231_REG_TEMP_LOW47   0x4d
92
93#define VT8231_REG_CONFIG 0x40
94#define VT8231_REG_ALARM1 0x41
95#define VT8231_REG_ALARM2 0x42
96#define VT8231_REG_VID    0x45
97#define VT8231_REG_FANDIV 0x47
98#define VT8231_REG_UCH_CONFIG 0x4a
99#define VT8231_REG_TEMP1_CONFIG 0x4b
100#define VT8231_REG_TEMP2_CONFIG 0x4c
101
102/* temps 1-7; voltages 0-6 */
103#define ISTEMP(i, ch_config) ((i) == 1 ? 1 : \
104                              (i) == 3 ? 1 : \
105                              (i) == 2 ? ((ch_config) >> 1) & 0x01 : \
106                                         ((ch_config) >> ((i)-1)) & 0x01)
107#define ISVOLT(i, ch_config) ((i) > 4 ? 1 : !(((ch_config) >> ((i)+2)) & 0x01))
108
109#define DIV_FROM_REG(val) (1 << (val))
110#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
111#define PWM_FROM_REG(val) (val)
112#define PWM_TO_REG(val) SENSORS_LIMIT((val), 0, 255)
113
114#define TEMP_FROM_REG(val) ((val)*10)
115#define TEMP_FROM_REG10(val) (((val)*10)/4)
116#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\
117                                                 ((val)+5)/10),0,255))
118#define IN_FROM_REG(val) /*(((val)*10+5)/10)*/ (val)
119#define IN_TO_REG(val)  (SENSORS_LIMIT((((val) * 10 + 5)/10),0,255))
120
121
122/********* FAN RPM CONVERSIONS ********/
123/* But this chip saturates back at 0, not at 255 like all the other chips.
124   So, 0 means 0 RPM */
125static inline u8 FAN_TO_REG(long rpm, int div)
126{
127        if (rpm == 0)
128                return 0;
129        rpm = SENSORS_LIMIT(rpm, 1, 1000000);
130        return SENSORS_LIMIT((1310720 + rpm * div / 2) / (rpm * div), 1, 255);
131}
132
133#define MIN_TO_REG(a,b) FAN_TO_REG(a,b)
134#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1310720/((val)*(div)))
135
136struct vt8231_data {
137        struct i2c_client client;
138        struct semaphore lock;
139        int sysctl_id;
140
141        struct semaphore update_lock;
142        char valid;             /* !=0 if following fields are valid */
143        unsigned long last_updated;     /* In jiffies */
144
145        u8 in[7];               /* Register value */
146        u8 in_max[7];           /* Register value */
147        u8 in_min[7];           /* Register value */
148        u16 temp[7];            /* Register value 10 bit */
149        u8 temp_over[7];        /* Register value */
150        u8 temp_hyst[7];        /* Register value */
151        u8 fan[2];              /* Register value */
152        u8 fan_min[2];          /* Register value */
153        u8 fan_div[2];          /* Register encoding, shifted right */
154        u16 alarms;             /* Register encoding */
155        u8 pwm[2];              /* Register value */
156        u8 pwm_ctl;             /* Register value */
157        u8 vid;                 /* Register encoding */
158        u8 vrm;
159        u8 uch_config;
160};
161
162static int vt8231_attach_adapter(struct i2c_adapter *adapter);
163static int vt8231_detect(struct i2c_adapter *adapter, int address,
164                          unsigned short flags, int kind);
165static int vt8231_detach_client(struct i2c_client *client);
166
167static inline int vt_rdval(struct i2c_client *client, u8 register);
168static inline void vt8231_write_value(struct i2c_client *client, u8 register,
169                               u8 value);
170static void vt8231_update_client(struct i2c_client *client);
171static void vt8231_init_client(struct i2c_client *client);
172static int vt8231_find(int *address);
173
174
175static void vt8231_fan(struct i2c_client *client, int operation,
176                        int ctl_name, int *nrels_mag, long *results);
177static void vt8231_alarms(struct i2c_client *client, int operation,
178                           int ctl_name, int *nrels_mag, long *results);
179static void vt8231_fan_div(struct i2c_client *client, int operation,
180                            int ctl_name, int *nrels_mag, long *results);
181static void vt8231_in(struct i2c_client *client, int operation,
182                        int ctl_name, int *nrels_mag, long *results);
183static void vt8231_pwm(struct i2c_client *client, int operation,
184                        int ctl_name, int *nrels_mag, long *results);
185static void vt8231_vid(struct i2c_client *client, int operation,
186                        int ctl_name, int *nrels_mag, long *results);
187static void vt8231_vrm(struct i2c_client *client, int operation,
188                        int ctl_name, int *nrels_mag, long *results);
189static void vt8231_uch(struct i2c_client *client, int operation,
190                        int ctl_name, int *nrels_mag, long *results);
191static void vt8231_temp(struct i2c_client *client, int operation,
192                        int ctl_name, int *nrels_mag, long *results);
193
194static struct i2c_driver vt8231_driver = {
195        .name           = "VT8231 sensors driver",
196        .id             = I2C_DRIVERID_VT8231,
197        .flags          = I2C_DF_NOTIFY,
198        .attach_adapter = vt8231_attach_adapter,
199        .detach_client  = vt8231_detach_client,
200};
201
202/* -- SENSORS SYSCTL START -- */
203#define VT8231_SYSCTL_IN0 1000
204#define VT8231_SYSCTL_IN1 1001
205#define VT8231_SYSCTL_IN2 1002
206#define VT8231_SYSCTL_IN3 1003
207#define VT8231_SYSCTL_IN4 1004
208#define VT8231_SYSCTL_IN5 1005
209#define VT8231_SYSCTL_IN6 1006
210#define VT8231_SYSCTL_FAN1 1101
211#define VT8231_SYSCTL_FAN2 1102
212#define VT8231_SYSCTL_TEMP 1200
213#define VT8231_SYSCTL_TEMP2 1201
214#define VT8231_SYSCTL_TEMP3 1202
215#define VT8231_SYSCTL_TEMP4 1203
216#define VT8231_SYSCTL_TEMP5 1204
217#define VT8231_SYSCTL_TEMP6 1205
218#define VT8231_SYSCTL_TEMP7 1206
219#define VT8231_SYSCTL_VID       1300
220#define VT8231_SYSCTL_PWM1      1401
221#define VT8231_SYSCTL_PWM2      1402
222#define VT8231_SYSCTL_VRM       1600
223#define VT8231_SYSCTL_UCH       1700
224#define VT8231_SYSCTL_FAN_DIV 2000
225#define VT8231_SYSCTL_ALARMS 2001
226
227#define VT8231_ALARM_IN1 0x01
228#define VT8231_ALARM_IN2 0x02
229#define VT8231_ALARM_IN5 0x04
230#define VT8231_ALARM_IN3 0x08
231#define VT8231_ALARM_TEMP 0x10
232#define VT8231_ALARM_FAN1 0x40
233#define VT8231_ALARM_FAN2 0x80
234#define VT8231_ALARM_IN4 0x100
235#define VT8231_ALARM_IN6 0x200
236#define VT8231_ALARM_TEMP2 0x800
237#define VT8231_ALARM_CHAS 0x1000
238#define VT8231_ALARM_TEMP3 0x8000
239/* duplicates */
240#define VT8231_ALARM_IN0 VT8231_ALARM_TEMP
241#define VT8231_ALARM_TEMP4 VT8231_ALARM_IN1
242#define VT8231_ALARM_TEMP5 VT8231_ALARM_IN2
243#define VT8231_ALARM_TEMP6 VT8231_ALARM_IN3
244#define VT8231_ALARM_TEMP7 VT8231_ALARM_IN4
245
246/* -- SENSORS SYSCTL END -- */
247
248static ctl_table vt8231_dir_table_template[] = {
249        {VT8231_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
250         &i2c_sysctl_real, NULL, &vt8231_in},
251        {VT8231_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real,
252         &i2c_sysctl_real, NULL, &vt8231_in},
253        {VT8231_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
254         &i2c_sysctl_real, NULL, &vt8231_in},
255        {VT8231_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
256         &i2c_sysctl_real, NULL, &vt8231_in},
257        {VT8231_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
258         &i2c_sysctl_real, NULL, &vt8231_in},
259        {VT8231_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real,
260         &i2c_sysctl_real, NULL, &vt8231_in},
261/*
262    not in 8231
263        {VT8231_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real,
264         &i2c_sysctl_real, NULL, &vt8231_in},
265        {VT8231_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
266         &i2c_sysctl_real, NULL, &vt8231_temp},
267*/
268        {VT8231_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL,
269         &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp},
270        {VT8231_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL,
271         &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp},
272        {VT8231_SYSCTL_TEMP4, "temp4", NULL, 0, 0644, NULL,
273         &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp},
274        {VT8231_SYSCTL_TEMP5, "temp5", NULL, 0, 0644, NULL,
275         &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp},
276        {VT8231_SYSCTL_TEMP6, "temp6", NULL, 0, 0644, NULL,
277         &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp},
278        {VT8231_SYSCTL_TEMP7, "temp7", NULL, 0, 0644, NULL,
279         &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp},
280        {VT8231_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
281         &i2c_sysctl_real, NULL, &vt8231_fan},
282        {VT8231_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
283         &i2c_sysctl_real, NULL, &vt8231_fan},
284        {VT8231_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
285         &i2c_sysctl_real, NULL, &vt8231_fan_div},
286        {VT8231_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
287         &i2c_sysctl_real, NULL, &vt8231_alarms},
288        {VT8231_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
289         &i2c_sysctl_real, NULL, &vt8231_pwm},
290        {VT8231_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real,
291         &i2c_sysctl_real, NULL, &vt8231_pwm},
292        {VT8231_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real,
293         &i2c_sysctl_real, NULL, &vt8231_vid},
294        {VT8231_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real,
295         &i2c_sysctl_real, NULL, &vt8231_vrm},
296        {VT8231_SYSCTL_UCH, "uch_config", NULL, 0, 0644, NULL, &i2c_proc_real,
297         &i2c_sysctl_real, NULL, &vt8231_uch},
298        {0}
299};
300
301static struct pci_dev *s_bridge;
302
303static int vt8231_attach_adapter(struct i2c_adapter *adapter)
304{
305        return i2c_detect(adapter, &addr_data, vt8231_detect);
306}
307
308/* Locate chip and get correct base address */
309static int vt8231_find(int *address)
310{
311        u16 val;
312
313        if (!pci_present())
314                return -ENODEV;
315
316        if (!(s_bridge = pci_find_device(PCI_VENDOR_ID_VIA,
317                                         0x8235, NULL)))
318                return -ENODEV;
319
320        if (PCIBIOS_SUCCESSFUL !=
321            pci_read_config_word(s_bridge, VIA686A_BASE_REG, &val))
322                return -ENODEV;
323        *address = val & ~(VIA686A_EXTENT - 1);
324        if (*address == 0 && force_addr == 0) {
325                printk("vt8231.o: base address not set - upgrade BIOS or use force_addr=0xaddr\n");
326                return -ENODEV;
327        }
328        if (force_addr)
329                *address = force_addr;  /* so detect will get called */
330
331        return 0;
332}
333
334int vt8231_detect(struct i2c_adapter *adapter, int address,
335                   unsigned short flags, int kind)
336{
337        int i;
338        struct i2c_client *new_client;
339        struct vt8231_data *data;
340        int err = 0;
341        const char *type_name = "vt8231";
342        u16 val;
343
344        if (!i2c_is_isa_adapter(adapter)) {
345                return 0;
346        }
347
348        /* 8231 requires multiple of 256 */
349        if(force_addr)
350                address = force_addr & 0xFF00;
351        if (check_region(address, VIA686A_EXTENT)) {
352                printk("vt8231.o: region 0x%x already in use!\n",
353                       address);
354                return -ENODEV;
355        }
356
357        if(force_addr) {
358                printk("vt8231.o: forcing ISA address 0x%04X\n", address);
359                if (PCIBIOS_SUCCESSFUL !=
360                    pci_write_config_word(s_bridge, VIA686A_BASE_REG, address))
361                        return -ENODEV;
362        }
363        if (PCIBIOS_SUCCESSFUL !=
364            pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val))
365                return -ENODEV;
366        if (!(val & 0x0001)) {
367                printk("vt8231.o: enabling sensors\n");
368                if (PCIBIOS_SUCCESSFUL !=
369                    pci_write_config_word(s_bridge, VIA686A_ENABLE_REG,
370                                      val | 0x0001))
371                        return -ENODEV;
372        }
373
374        if (!(data = kmalloc(sizeof(struct vt8231_data), GFP_KERNEL))) {
375                err = -ENOMEM;
376                goto ERROR0;
377        }
378
379        new_client = &data->client;
380        new_client->addr = address;
381        init_MUTEX(&data->lock);
382        new_client->data = data;
383        new_client->adapter = adapter;
384        new_client->driver = &vt8231_driver;
385        new_client->flags = 0;
386
387        /* Reserve the ISA region */
388        request_region(address, VIA686A_EXTENT, "vt8231-sensors");
389
390        /* Fill in the remaining client fields and put into the global list */
391        strcpy(new_client->name, "Via 8231 Integrated Sensors");
392        data->valid = 0;
393        init_MUTEX(&data->update_lock);
394
395        /* Tell the I2C layer a new client has arrived */
396        if ((err = i2c_attach_client(new_client)))
397                goto ERROR3;
398
399        /* Register a new directory entry with module sensors */
400        if ((i = i2c_register_entry((struct i2c_client *) new_client,
401                                        type_name,
402                                        vt8231_dir_table_template,
403                                        THIS_MODULE)) < 0) {
404                err = i;
405                goto ERROR4;
406        }
407        data->sysctl_id = i;
408
409        vt8231_init_client(new_client);
410        return 0;
411
412      ERROR4:
413        i2c_detach_client(new_client);
414      ERROR3:
415        release_region(address, VIA686A_EXTENT);
416        kfree(data);
417      ERROR0:
418        return err;
419}
420
421static int vt8231_detach_client(struct i2c_client *client)
422{
423        int err;
424
425        i2c_deregister_entry(((struct vt8231_data *) (client->data))->
426                                 sysctl_id);
427
428        if ((err = i2c_detach_client(client))) {
429                printk
430                    ("vt8231.o: Client deregistration failed, client not detached.\n");
431                return err;
432        }
433
434        release_region(client->addr, VIA686A_EXTENT);
435        kfree(client->data);
436
437        return 0;
438}
439
440
441static inline int vt_rdval(struct i2c_client *client, u8 reg)
442{
443        return (inb_p(client->addr + reg));
444}
445
446static inline void vt8231_write_value(struct i2c_client *client, u8 reg, u8 value)
447{
448        outb_p(value, client->addr + reg);
449}
450
451static void vt8231_init_client(struct i2c_client *client)
452{
453        struct vt8231_data *data = client->data;
454
455        data->vrm = DEFAULT_VRM;
456        /* set "default" interrupt mode for alarms, which isn't the default */
457        vt8231_write_value(client, VT8231_REG_TEMP1_CONFIG, 0);
458        vt8231_write_value(client, VT8231_REG_TEMP2_CONFIG, 0);
459}
460
461static void vt8231_update_client(struct i2c_client *client)
462{
463        struct vt8231_data *data = client->data;
464        int i, j;
465
466        down(&data->update_lock);
467
468        if ((jiffies - data->last_updated > HZ + HZ / 2) ||
469            (jiffies < data->last_updated) || !data->valid) {
470                data->uch_config = vt_rdval(client, VT8231_REG_UCH_CONFIG);
471                for (i = 0; i <= 5; i++) {
472                        if(ISVOLT(i, data->uch_config)) {
473                                data->in[i] = vt_rdval(client, VT8231_REG_IN(i));
474                                data->in_min[i] = vt_rdval(client,
475                                                        VT8231_REG_IN_MIN(i));
476                                data->in_max[i] = vt_rdval(client,
477                                                        VT8231_REG_IN_MAX(i));
478                        } else {
479                                data->in[i] = 0;
480                                data->in_min[i] = 0;
481                                data->in_max[i] = 0;
482                        }
483                }
484                for (i = 1; i <= 2; i++) {
485                        data->fan[i - 1] = vt_rdval(client, VT8231_REG_FAN(i));
486                        data->fan_min[i - 1] = vt_rdval(client,
487                                                     VT8231_REG_FAN_MIN(i));
488                }
489                for (i = 2; i <= 7; i++) {
490                        if(ISTEMP(i, data->uch_config)) {
491                                data->temp[i - 1] = vt_rdval(client,
492                                                     VT8231_REG_TEMP(i)) << 2;
493                                switch(i) {
494                                        case 1:
495                                                /* ? */
496                                                j = 0;
497                                                break;
498                                        case 2:
499                                                j = (vt_rdval(client,
500                                                  VT8231_REG_TEMP_LOW2) &
501                                                                    0x30) >> 4;
502                                                break;
503                                        case 3:
504                                                j = (vt_rdval(client,
505                                                  VT8231_REG_TEMP_LOW3) &
506                                                                    0xc0) >> 6;
507                                                break;
508                                        case 4:
509                                        case 5:
510                                        case 6:
511                                        case 7:
512                                        default:
513                                                j = (vt_rdval(client,
514                                                  VT8231_REG_TEMP_LOW47) >>
515                                                            ((i-4)*2)) & 0x03; 
516                                                break;
517       
518                                }
519                                data->temp[i - 1] |= j;
520                                data->temp_over[i - 1] = vt_rdval(client,
521                                                      VT8231_REG_TEMP_OVER(i));
522                                data->temp_hyst[i - 1] = vt_rdval(client,
523                                                      VT8231_REG_TEMP_HYST(i));
524                        } else {
525                                data->temp[i - 1] = 0;
526                                data->temp_over[i - 1] = 0;
527                                data->temp_hyst[i - 1] = 0;
528                        }
529                }
530
531                for (i = 1; i <= 2; i++) {
532                        data->fan[i - 1] = vt_rdval(client, VT8231_REG_FAN(i));
533                        data->fan_min[i - 1] = vt_rdval(client,
534                                                        VT8231_REG_FAN_MIN(i));
535                        data->pwm[i - 1] = vt_rdval(client, VT8231_REG_PWM(i));
536                }
537
538                data->pwm_ctl = vt_rdval(client, VT8231_REG_PWM_CTL);
539                i = vt_rdval(client, VT8231_REG_FANDIV);
540                data->fan_div[0] = (i >> 4) & 0x03;
541                data->fan_div[1] = i >> 6;
542                data->alarms = vt_rdval(client, VT8231_REG_ALARM1) |
543                                    (vt_rdval(client, VT8231_REG_ALARM2) << 8);
544                data->vid= vt_rdval(client, VT8231_REG_VID) & 0x1f;
545                data->last_updated = jiffies;
546                data->valid = 1;
547        }
548
549        up(&data->update_lock);
550}
551
552
553void vt8231_in(struct i2c_client *client, int operation, int ctl_name,
554                int *nrels_mag, long *results)
555{
556        struct vt8231_data *data = client->data;
557        int nr = ctl_name - VT8231_SYSCTL_IN0;
558
559        if (operation == SENSORS_PROC_REAL_INFO)
560                *nrels_mag = 2;
561        else if (operation == SENSORS_PROC_REAL_READ) {
562                vt8231_update_client(client);
563                results[0] = IN_FROM_REG(data->in_min[nr]);
564                results[1] = IN_FROM_REG(data->in_max[nr]);
565                results[2] = IN_FROM_REG(data->in[nr]);
566                *nrels_mag = 3;
567        } else if (operation == SENSORS_PROC_REAL_WRITE) {
568                if (*nrels_mag >= 1) {
569                        data->in_min[nr] = IN_TO_REG(results[0]);
570                        vt8231_write_value(client, VT8231_REG_IN_MIN(nr),
571                                            data->in_min[nr]);
572                }
573                if (*nrels_mag >= 2) {
574                        data->in_max[nr] = IN_TO_REG(results[1]);
575                        vt8231_write_value(client, VT8231_REG_IN_MAX(nr),
576                                            data->in_max[nr]);
577                }
578        }
579}
580
581void vt8231_fan(struct i2c_client *client, int operation, int ctl_name,
582                 int *nrels_mag, long *results)
583{
584        struct vt8231_data *data = client->data;
585        int nr = ctl_name - VT8231_SYSCTL_FAN1 + 1;
586
587        if (operation == SENSORS_PROC_REAL_INFO)
588                *nrels_mag = 0;
589        else if (operation == SENSORS_PROC_REAL_READ) {
590                vt8231_update_client(client);
591                results[0] = FAN_FROM_REG(data->fan_min[nr - 1],
592                                          DIV_FROM_REG(data->fan_div
593                                                       [nr - 1]));
594                results[1] = FAN_FROM_REG(data->fan[nr - 1],
595                                 DIV_FROM_REG(data->fan_div[nr - 1]));
596                *nrels_mag = 2;
597        } else if (operation == SENSORS_PROC_REAL_WRITE) {
598                if (*nrels_mag >= 1) {
599                        data->fan_min[nr - 1] = MIN_TO_REG(results[0],
600                                                           DIV_FROM_REG
601                                                           (data->
602                                                            fan_div[nr-1]));
603                        vt8231_write_value(client, VT8231_REG_FAN_MIN(nr),
604                                            data->fan_min[nr - 1]);
605                }
606        }
607}
608
609
610void vt8231_temp(struct i2c_client *client, int operation, int ctl_name,
611                  int *nrels_mag, long *results)
612{
613        struct vt8231_data *data = client->data;
614        int nr = ctl_name - VT8231_SYSCTL_TEMP;
615
616        if (operation == SENSORS_PROC_REAL_INFO)
617                *nrels_mag = 1;
618        else if (operation == SENSORS_PROC_REAL_READ) {
619                vt8231_update_client(client);
620                results[0] = TEMP_FROM_REG(data->temp_over[nr]);
621                results[1] = TEMP_FROM_REG(data->temp_hyst[nr]);
622                results[2] = TEMP_FROM_REG10(data->temp[nr]);
623                *nrels_mag = 3;
624        } else if (operation == SENSORS_PROC_REAL_WRITE) {
625                if (*nrels_mag >= 1) {
626                        data->temp_over[nr] = TEMP_TO_REG(results[0]);
627                        vt8231_write_value(client,
628                                            VT8231_REG_TEMP_OVER(nr + 1),
629                                            data->temp_over[nr]);
630                }
631                if (*nrels_mag >= 2) {
632                        data->temp_hyst[nr] = TEMP_TO_REG(results[1]);
633                        vt8231_write_value(client,
634                                            VT8231_REG_TEMP_HYST(nr + 1),
635                                            data->temp_hyst[nr]);
636                }
637        }
638}
639
640void vt8231_alarms(struct i2c_client *client, int operation, int ctl_name,
641                    int *nrels_mag, long *results)
642{
643        struct vt8231_data *data = client->data;
644        if (operation == SENSORS_PROC_REAL_INFO)
645                *nrels_mag = 0;
646        else if (operation == SENSORS_PROC_REAL_READ) {
647                vt8231_update_client(client);
648                results[0] = data->alarms;
649                *nrels_mag = 1;
650        }
651}
652
653void vt8231_fan_div(struct i2c_client *client, int operation,
654                     int ctl_name, int *nrels_mag, long *results)
655{
656        struct vt8231_data *data = client->data;
657        int old;
658
659        if (operation == SENSORS_PROC_REAL_INFO)
660                *nrels_mag = 0;
661        else if (operation == SENSORS_PROC_REAL_READ) {
662                vt8231_update_client(client);
663                results[0] = DIV_FROM_REG(data->fan_div[0]);
664                results[1] = DIV_FROM_REG(data->fan_div[1]);
665                *nrels_mag = 2;
666        } else if (operation == SENSORS_PROC_REAL_WRITE) {
667                old = vt_rdval(client, VT8231_REG_FANDIV);
668                if (*nrels_mag >= 2) {
669                        data->fan_div[1] = DIV_TO_REG(results[1]);
670                        old = (old & 0x3f) | (data->fan_div[1] << 6);
671                }
672                if (*nrels_mag >= 1) {
673                        data->fan_div[0] = DIV_TO_REG(results[0]);
674                        old = (old & 0xcf) | (data->fan_div[0] << 4);
675                        vt8231_write_value(client, VT8231_REG_FANDIV, old);
676                }
677        }
678}
679
680void vt8231_pwm(struct i2c_client *client, int operation, int ctl_name,
681                 int *nrels_mag, long *results)
682{
683        struct vt8231_data *data = client->data;
684        int nr = 1 + ctl_name - VT8231_SYSCTL_PWM1;
685
686        if (operation == SENSORS_PROC_REAL_INFO)
687                *nrels_mag = 0;
688        else if (operation == SENSORS_PROC_REAL_READ) {
689                vt8231_update_client(client);
690                results[0] = PWM_FROM_REG(data->pwm[nr - 1]);
691                results[1] = (data->pwm_ctl >> (3 + (4 * (nr - 1)))) & 1;
692                *nrels_mag = 2;
693        } else if (operation == SENSORS_PROC_REAL_WRITE) {
694                if (*nrels_mag >= 1) {
695                        data->pwm[nr - 1] = PWM_TO_REG(results[0]);
696                        if (*nrels_mag >= 2) {
697                                if(results[1]) {
698                                        data->pwm_ctl |=
699                                                  (0x08 << (4 * (nr - 1)));
700                                        vt8231_write_value(client,
701                                                           VT8231_REG_PWM_CTL, 
702                                                           data->pwm_ctl);
703                                } else {
704                                        data->pwm_ctl &=
705                                                ~ (0x08 << (4 * (nr - 1)));
706                                        vt8231_write_value(client,
707                                                           VT8231_REG_PWM_CTL, 
708                                                           data->pwm_ctl);
709                                }
710                        }
711                        vt8231_write_value(client, VT8231_REG_PWM(nr),
712                                            data->pwm[nr - 1]);
713                }
714        }
715}
716
717void vt8231_vid(struct i2c_client *client, int operation, int ctl_name,
718                 int *nrels_mag, long *results)
719{
720        struct vt8231_data *data = client->data;
721        if (operation == SENSORS_PROC_REAL_INFO)
722                *nrels_mag = 3;
723        else if (operation == SENSORS_PROC_REAL_READ) {
724                vt8231_update_client(client);
725                results[0] = vid_from_reg(data->vid, data->vrm);
726                *nrels_mag = 1;
727        }
728}
729
730void vt8231_vrm(struct i2c_client *client, int operation, int ctl_name,
731                 int *nrels_mag, long *results)
732{
733        struct vt8231_data *data = client->data;
734        if (operation == SENSORS_PROC_REAL_INFO)
735                *nrels_mag = 1;
736        else if (operation == SENSORS_PROC_REAL_READ) {
737                results[0] = data->vrm;
738                *nrels_mag = 1;
739        } else if (operation == SENSORS_PROC_REAL_WRITE) {
740                if (*nrels_mag >= 1)
741                        data->vrm = results[0];
742        }
743}
744
745void vt8231_uch(struct i2c_client *client, int operation, int ctl_name,
746                 int *nrels_mag, long *results)
747{
748        struct vt8231_data *data = client->data;
749        if (operation == SENSORS_PROC_REAL_INFO)
750                *nrels_mag = 0;
751        else if (operation == SENSORS_PROC_REAL_READ) {
752                results[0] = data->uch_config & 0x7c;
753                *nrels_mag = 1;
754        } else if (operation == SENSORS_PROC_REAL_WRITE) {
755                if (*nrels_mag >= 1) {
756                        data->uch_config = (data->uch_config & 0x83)|(results[0] & 0x7c);
757                        vt8231_write_value(client, VT8231_REG_UCH_CONFIG,
758                                           data->uch_config);
759                }
760        }
761}
762
763static int __init sm_vt8231_init(void)
764{
765        int addr;
766
767        printk("vt8231.o version %s (%s)\n", LM_VERSION, LM_DATE);
768
769        if (vt8231_find(&addr)) {
770                printk("vt8231.o: VT8231 not detected, module not inserted.\n");
771                return -ENODEV;
772        }
773        normal_isa[0] = addr;
774
775        return i2c_add_driver(&vt8231_driver);}
776
777static void __exit sm_vt8231_exit(void)
778{
779        i2c_del_driver(&vt8231_driver);
780}
781
782
783
784MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
785MODULE_DESCRIPTION("VT8231 sensors");
786MODULE_LICENSE("GPL");
787
788module_init(sm_vt8231_init);
789module_exit(sm_vt8231_exit);
Note: See TracBrowser for help on using the browser.