root/lm-sensors/trunk/kernel/chips/asb100.c @ 5146

Revision 5146, 29.5 KB (checked in by khali, 5 years ago)

Drop unused defines.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    asb100.c - Part of lm_sensors, Linux kernel modules for hardware
3                monitoring
4
5    Copyright (c) 2003 Mark M. Hoffman <mhoffman@lightlink.com>
6
7        (derived from w83781d.c)
8
9    Copyright (c) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
10    Philip Edelbrock <phil@netroedge.com>, and
11    Mark Studebaker <mdsxyz123@yahoo.com>
12
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/
27
28/*
29    This driver supports the hardware sensor chips: Asus ASB100 and
30    ASB100-A "BACH".
31
32    ASB100-A supports pwm1, while plain ASB100 does not.  There is no known
33    way for the driver to tell which one is there.
34
35    Chip        #vin    #fanin  #pwm    #temp   wchipid vendid  i2c     ISA
36    asb100      7       3       1       4       0x31    0x0694  yes     no
37*/
38
39//#define DEBUG 1
40
41#include <linux/module.h>
42#include <linux/slab.h>
43#include <linux/i2c.h>
44#include <linux/i2c-proc.h>
45#include <linux/init.h>
46#include "version.h"
47#include "sensors_vid.h"
48#include "lm75.h"
49
50#ifndef I2C_DRIVERID_ASB100
51#define I2C_DRIVERID_ASB100             1043
52#endif
53
54/* I2C addresses to scan */
55static unsigned short normal_i2c[] = { 0x2d, SENSORS_I2C_END };
56static unsigned short normal_i2c_range[] = { SENSORS_I2C_END };
57
58/* ISA addresses to scan (none) */
59static unsigned int normal_isa[] = { SENSORS_ISA_END };
60static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
61
62/* default VRM to 9.0 */
63#define ASB100_DEFAULT_VRM 90
64
65/* Insmod parameters */
66SENSORS_INSMOD_1(asb100);
67SENSORS_MODULE_PARM(force_subclients, "List of subclient addresses: " \
68        "{bus, clientaddr, subclientaddr1, subclientaddr2}");
69
70/* Voltage IN registers 0-6 */
71#define ASB100_REG_IN(nr)     (0x20 + (nr))
72#define ASB100_REG_IN_MAX(nr) (0x2b + (nr * 2))
73#define ASB100_REG_IN_MIN(nr) (0x2c + (nr * 2))
74
75/* FAN IN registers 1-3 */
76#define ASB100_REG_FAN(nr)     (0x27 + (nr))
77#define ASB100_REG_FAN_MIN(nr) (0x3a + (nr))
78
79/* TEMPERATURE registers 1-4 */
80static const u16 asb100_reg_temp[]      = {0, 0x27, 0x150, 0x250, 0x17};
81static const u16 asb100_reg_temp_max[]  = {0, 0x39, 0x155, 0x255, 0x18};
82static const u16 asb100_reg_temp_hyst[] = {0, 0x3a, 0x153, 0x253, 0x19};
83
84#define ASB100_REG_TEMP(nr) (asb100_reg_temp[nr])
85#define ASB100_REG_TEMP_MAX(nr) (asb100_reg_temp_max[nr])
86#define ASB100_REG_TEMP_HYST(nr) (asb100_reg_temp_hyst[nr])
87
88#define ASB100_REG_TEMP2_CONFIG 0x0152
89#define ASB100_REG_TEMP3_CONFIG 0x0252
90
91
92#define ASB100_REG_CONFIG       0x40
93#define ASB100_REG_ALARM1       0x41
94#define ASB100_REG_ALARM2       0x42
95#define ASB100_REG_SMIM1        0x43
96#define ASB100_REG_SMIM2        0x44
97#define ASB100_REG_VID_FANDIV   0x47
98#define ASB100_REG_I2C_ADDR     0x48
99#define ASB100_REG_CHIPID       0x49
100#define ASB100_REG_I2C_SUBADDR  0x4a
101#define ASB100_REG_PIN          0x4b
102#define ASB100_REG_IRQ          0x4c
103#define ASB100_REG_BANK         0x4e
104#define ASB100_REG_CHIPMAN      0x4f
105
106#define ASB100_REG_WCHIPID      0x58
107
108/* bit 7 -> enable, bits 0-3 -> duty cycle */
109#define ASB100_REG_PWM1         0x59
110
111/* CONVERSIONS
112   Rounding and limit checking is only done on the TO_REG variants. */
113
114/* These constants are a guess, consistent w/ w83781d */
115#define ASB100_IN_MIN (  0)
116#define ASB100_IN_MAX (408)
117
118/* IN: 1/100 V (0V to 4.08V)
119   REG: 16mV/bit */
120static u8 IN_TO_REG(unsigned val)
121{
122        unsigned nval = SENSORS_LIMIT(val, ASB100_IN_MIN, ASB100_IN_MAX);
123        return (nval * 10 + 8) / 16;
124}
125
126static unsigned IN_FROM_REG(u8 reg)
127{
128        return (reg * 16 + 5) / 10;
129}
130
131static u8 FAN_TO_REG(long rpm, int div)
132{
133        if (rpm == 0)
134                return 255;
135        rpm = SENSORS_LIMIT(rpm, 1, 1000000);
136        return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
137}
138
139static int FAN_FROM_REG(u8 val, int div)
140{
141        return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
142}
143
144/* These constants are a guess, consistent w/ w83781d */
145#define ASB100_TEMP_MIN (-1280)
146#define ASB100_TEMP_MAX ( 1270)
147
148/* TEMP: 1/10 degrees C (-128C to +127C)
149   REG: 1C/bit, two's complement */
150static u8 TEMP_TO_REG(int temp)
151{
152        int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX);
153        ntemp += (ntemp<0 ? -5 : 5);
154        return (u8)(ntemp / 10);
155}
156
157static int TEMP_FROM_REG(u8 reg)
158{
159        return (s8)reg * 10;
160}
161
162/* PWM: 0 - 255 per sensors documentation
163   REG: (6.25% duty cycle per bit) */
164static u8 ASB100_PWM_TO_REG(int pwm)
165{
166        pwm = SENSORS_LIMIT(pwm, 0, 255);
167        return (u8)(pwm / 16);
168}
169
170static int ASB100_PWM_FROM_REG(u8 reg)
171{
172        return reg * 16;
173}
174
175#define ALARMS_FROM_REG(val) (val)
176
177#define DIV_FROM_REG(val) (1 << (val))
178
179/* FAN DIV: 1, 2, 4, or 8 (defaults to 2)
180   REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */
181static u8 DIV_TO_REG(long val)
182{
183        return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1;
184}
185
186/* For each registered client, we need to keep some data in memory. That
187   data is pointed to by client->data. The structure itself is
188   dynamically allocated, at the same time the client itself is allocated. */
189struct asb100_data {
190        struct i2c_client client;
191        struct semaphore lock;
192        int sysctl_id;
193        enum chips type;
194
195        struct semaphore update_lock;
196        unsigned long last_updated;     /* In jiffies */
197
198        /* array of 2 pointers to subclients */
199        struct i2c_client *lm75[2];
200
201        char valid;             /* !=0 if following fields are valid */
202        u8 in[7];               /* Register value */
203        u8 in_max[7];           /* Register value */
204        u8 in_min[7];           /* Register value */
205        u8 fan[3];              /* Register value */
206        u8 fan_min[3];          /* Register value */
207        u16 temp[4];            /* Register value (0 and 3 are u8 only) */
208        u16 temp_max[4];        /* Register value (0 and 3 are u8 only) */
209        u16 temp_hyst[4];       /* Register value (0 and 3 are u8 only) */
210        u8 fan_div[3];          /* Register encoding, right justified */
211        u8 pwm;                 /* Register encoding */
212        u8 vid;                 /* Register encoding, combined */
213        u32 alarms;             /* Register encoding, combined */
214        u8 vrm;
215};
216
217static int asb100_attach_adapter(struct i2c_adapter *adapter);
218static int asb100_detect(struct i2c_adapter *adapter, int address,
219                unsigned short flags, int kind);
220static int asb100_detach_client(struct i2c_client *client);
221
222static int asb100_read_value(struct i2c_client *client, u16 reg);
223static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val);
224static void asb100_update_client(struct i2c_client *client);
225static void asb100_init_client(struct i2c_client *client);
226
227static void asb100_in(struct i2c_client *client, int operation,
228                int ctl_name, int *nrels_mag, long *results);
229static void asb100_fan(struct i2c_client *client, int operation,
230                int ctl_name, int *nrels_mag, long *results);
231static void asb100_temp(struct i2c_client *client, int operation,
232                int ctl_name, int *nrels_mag, long *results);
233static void asb100_temp_add(struct i2c_client *client, int operation,
234                int ctl_name, int *nrels_mag, long *results);
235static void asb100_vid(struct i2c_client *client, int operation,
236                int ctl_name, int *nrels_mag, long *results);
237static void asb100_vrm(struct i2c_client *client, int operation,
238                int ctl_name, int *nrels_mag, long *results);
239static void asb100_alarms(struct i2c_client *client, int operation,
240                int ctl_name, int *nrels_mag, long *results);
241static void asb100_fan_div(struct i2c_client *client, int operation,
242                int ctl_name, int *nrels_mag, long *results);
243static void asb100_pwm(struct i2c_client *client, int operation,
244                int ctl_name, int *nrels_mag, long *results);
245
246static struct i2c_driver asb100_driver = {
247        .name           = "asb100",
248        .id             = I2C_DRIVERID_ASB100,
249        .flags          = I2C_DF_NOTIFY,
250        .attach_adapter = asb100_attach_adapter,
251        .detach_client  = asb100_detach_client,
252};
253
254/* The /proc/sys entries */
255/* -- SENSORS SYSCTL START -- */
256
257#define ASB100_SYSCTL_IN0       1000    /* Volts * 100 */
258#define ASB100_SYSCTL_IN1       1001
259#define ASB100_SYSCTL_IN2       1002
260#define ASB100_SYSCTL_IN3       1003
261#define ASB100_SYSCTL_IN4       1004
262#define ASB100_SYSCTL_IN5       1005
263#define ASB100_SYSCTL_IN6       1006
264
265#define ASB100_SYSCTL_FAN1      1101    /* Rotations/min */
266#define ASB100_SYSCTL_FAN2      1102
267#define ASB100_SYSCTL_FAN3      1103
268
269#define ASB100_SYSCTL_TEMP1     1200    /* Degrees Celsius * 10 */
270#define ASB100_SYSCTL_TEMP2     1201
271#define ASB100_SYSCTL_TEMP3     1202
272#define ASB100_SYSCTL_TEMP4     1203
273
274#define ASB100_SYSCTL_VID       1300    /* Volts * 1000 */
275#define ASB100_SYSCTL_VRM       1301
276
277#define ASB100_SYSCTL_PWM1      1401    /* 0-255 => 0-100% duty cycle */
278
279#define ASB100_SYSCTL_FAN_DIV   2000    /* 1, 2, 4 or 8 */
280#define ASB100_SYSCTL_ALARMS    2001    /* bitvector */
281
282#define ASB100_ALARM_IN0        0x0001  /* ? */
283#define ASB100_ALARM_IN1        0x0002  /* ? */
284#define ASB100_ALARM_IN2        0x0004
285#define ASB100_ALARM_IN3        0x0008
286#define ASB100_ALARM_TEMP1      0x0010
287#define ASB100_ALARM_TEMP2      0x0020
288#define ASB100_ALARM_FAN1       0x0040
289#define ASB100_ALARM_FAN2       0x0080
290#define ASB100_ALARM_IN4        0x0100
291#define ASB100_ALARM_IN5        0x0200  /* ? */
292#define ASB100_ALARM_IN6        0x0400  /* ? */
293#define ASB100_ALARM_FAN3       0x0800
294#define ASB100_ALARM_CHAS       0x1000
295#define ASB100_ALARM_TEMP3      0x2000
296
297/* -- SENSORS SYSCTL END -- */
298
299/* These files are created for each detected chip. This is just a template;
300   though at first sight, you might think we could use a statically
301   allocated list, we need some way to get back to the parent - which
302   is done through one of the 'extra' fields which are initialized
303   when a new copy is allocated. */
304
305/* no datasheet - but we did get some hints from someone who
306   claimed to have the datasheet */
307#define ASB100_SYSCTL_IN(nr) {ASB100_SYSCTL_IN##nr, "in" #nr, NULL, 0, \
308        0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &asb100_in}
309#define ASB100_SYSCTL_FAN(nr) {ASB100_SYSCTL_FAN##nr, "fan" #nr, NULL, 0, \
310        0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &asb100_fan}
311#define ASB100_SYSCTL_TEMP(nr, func) {ASB100_SYSCTL_TEMP##nr, "temp" #nr, \
312        NULL, 0, 0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, func}
313static ctl_table asb100_dir_table_template[] = {
314        ASB100_SYSCTL_IN(0),
315        ASB100_SYSCTL_IN(1),
316        ASB100_SYSCTL_IN(2),
317        ASB100_SYSCTL_IN(3),
318        ASB100_SYSCTL_IN(4),
319        ASB100_SYSCTL_IN(5),
320        ASB100_SYSCTL_IN(6),
321
322        ASB100_SYSCTL_FAN(1),
323        ASB100_SYSCTL_FAN(2),
324        ASB100_SYSCTL_FAN(3),
325
326        ASB100_SYSCTL_TEMP(1, &asb100_temp),
327        ASB100_SYSCTL_TEMP(2, &asb100_temp_add),
328        ASB100_SYSCTL_TEMP(3, &asb100_temp_add),
329        ASB100_SYSCTL_TEMP(4, &asb100_temp),
330
331        {ASB100_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real,
332         &i2c_sysctl_real, NULL, &asb100_vid},
333        {ASB100_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real,
334         &i2c_sysctl_real, NULL, &asb100_vrm},
335        {ASB100_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
336         &i2c_sysctl_real, NULL, &asb100_fan_div},
337        {ASB100_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
338         &i2c_sysctl_real, NULL, &asb100_alarms},
339        {ASB100_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
340         &i2c_sysctl_real, NULL, &asb100_pwm},
341        {0}
342};
343
344/* This function is called when:
345        asb100_driver is inserted (when this module is loaded), for each
346                available adapter
347        when a new adapter is inserted (and asb100_driver is still present)
348 */
349static int asb100_attach_adapter(struct i2c_adapter *adapter)
350{
351        return i2c_detect(adapter, &addr_data, asb100_detect);
352}
353
354static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
355                int kind, struct i2c_client *new_client)
356{
357        int i, id, err = 0;
358        struct asb100_data *data = new_client->data;
359
360        data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
361        if (!(data->lm75[0])) {
362                err = -ENOMEM;
363                goto ERROR_SC_0;
364        }
365        memset(data->lm75[0], 0x00, sizeof(struct i2c_client));
366
367        data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
368        if (!(data->lm75[1])) {
369                err = -ENOMEM;
370                goto ERROR_SC_1;
371        }
372        memset(data->lm75[1], 0x00, sizeof(struct i2c_client));
373
374        id = i2c_adapter_id(adapter);
375
376        if (force_subclients[0] == id && force_subclients[1] == address) {
377                for (i = 2; i <= 3; i++) {
378                        if (force_subclients[i] < 0x48 ||
379                                force_subclients[i] > 0x4f) {
380                                printk(KERN_ERR "asb100.o: invalid subclient "
381                                        "address %d; must be 0x48-0x4f\n",
382                                        force_subclients[i]);
383                                goto ERROR_SC_2;
384                        }
385                }
386                asb100_write_value(new_client, ASB100_REG_I2C_SUBADDR,
387                                    (force_subclients[2] & 0x07) |
388                                    ((force_subclients[3] & 0x07) <<4));
389                data->lm75[0]->addr = force_subclients[2];
390                data->lm75[1]->addr = force_subclients[3];
391        } else {
392                int val = asb100_read_value(new_client, ASB100_REG_I2C_SUBADDR);
393                data->lm75[0]->addr = 0x48 + (val & 0x07);
394                data->lm75[1]->addr = 0x48 + ((val >> 4) & 0x07);
395        }
396
397        if(data->lm75[0]->addr == data->lm75[1]->addr) {
398                printk(KERN_ERR "asb100.o: duplicate addresses 0x%x "
399                                "for subclients\n", data->lm75[0]->addr);
400                goto ERROR_SC_2;
401        }
402
403        for (i = 0; i <= 1; i++) {
404                data->lm75[i]->data = NULL;
405                data->lm75[i]->adapter = adapter;
406                data->lm75[i]->driver = &asb100_driver;
407                data->lm75[i]->flags = 0;
408                strcpy(data->lm75[i]->name, "asb100 subclient");
409        }
410
411        if ((err = i2c_attach_client(data->lm75[0]))) {
412                printk(KERN_ERR "asb100.o: Subclient %d registration "
413                        "at address 0x%x failed.\n", i, data->lm75[0]->addr);
414                goto ERROR_SC_2;
415        }
416
417        if ((err = i2c_attach_client(data->lm75[1]))) {
418                printk(KERN_ERR "asb100.o: Subclient %d registration "
419                        "at address 0x%x failed.\n", i, data->lm75[1]->addr);
420                goto ERROR_SC_3;
421        }
422
423        return 0;
424
425/* Undo inits in case of errors */
426ERROR_SC_3:
427        i2c_detach_client(data->lm75[0]);
428ERROR_SC_2:
429        kfree(data->lm75[1]);
430ERROR_SC_1:
431        kfree(data->lm75[0]);
432ERROR_SC_0:
433        return err;
434}
435
436static int asb100_detect(struct i2c_adapter *adapter, int address,
437                unsigned short flags, int kind)
438{
439        int err = 0;
440        struct i2c_client *new_client;
441        struct asb100_data *data;
442
443        /* asb100 is SMBus only */
444        if (i2c_is_isa_adapter(adapter)) {
445                pr_debug("asb100.o: detect failed, "
446                                "cannot attach to legacy adapter!\n");
447                goto ERROR0;
448        }
449
450        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
451                pr_debug("asb100.o: detect failed, "
452                                "smbus byte data not supported!\n");
453                goto ERROR0;
454        }
455
456        /* OK. For now, we presume we have a valid client. We now create the
457           client structure, even though we cannot fill it completely yet.
458           But it allows us to access asb100_{read,write}_value. */
459
460        if (!(data = kmalloc(sizeof(struct asb100_data), GFP_KERNEL))) {
461                pr_debug("asb100.o: detect failed, kmalloc failed!\n");
462                err = -ENOMEM;
463                goto ERROR0;
464        }
465
466        new_client = &data->client;
467        new_client->addr = address;
468        init_MUTEX(&data->lock);
469        new_client->data = data;
470        new_client->adapter = adapter;
471        new_client->driver = &asb100_driver;
472        new_client->flags = 0;
473
474        /* Now, we do the remaining detection. */
475
476        /* The chip may be stuck in some other bank than bank 0. This may
477           make reading other information impossible. Specify a force=... or
478           force_*=... parameter, and the chip will be reset to the right
479           bank. */
480        if (kind < 0) {
481
482                int val1 = asb100_read_value(new_client, ASB100_REG_BANK);
483                int val2 = asb100_read_value(new_client, ASB100_REG_CHIPMAN);
484
485                /* If we're in bank 0 */
486                if ( (!(val1 & 0x07)) &&
487                                /* Check for ASB100 ID (low byte) */
488                                ( ((!(val1 & 0x80)) && (val2 != 0x94)) ||
489                                /* Check for ASB100 ID (high byte ) */
490                                ((val1 & 0x80) && (val2 != 0x06)) ) ) {
491                        pr_debug("asb100.o: detect failed, "
492                                        "bad chip id 0x%02x!\n", val2);
493                        goto ERROR1;
494                }
495
496        } /* kind < 0 */
497
498        /* We have either had a force parameter, or we have already detected
499           Winbond. Put it now into bank 0 and Vendor ID High Byte */
500        asb100_write_value(new_client, ASB100_REG_BANK,
501                (asb100_read_value(new_client, ASB100_REG_BANK) & 0x78) | 0x80);
502
503        /* Determine the chip type. */
504        if (kind <= 0) {
505                int val1 = asb100_read_value(new_client, ASB100_REG_WCHIPID);
506                int val2 = asb100_read_value(new_client, ASB100_REG_CHIPMAN);
507
508                if ((val1 == 0x31) && (val2 == 0x06))
509                        kind = asb100;
510                else {
511                        if (kind == 0)
512                                printk (KERN_WARNING "asb100.o: Ignoring "
513                                        "'force' parameter for unknown chip "
514                                        "at adapter %d, address 0x%02x.\n",
515                                        i2c_adapter_id(adapter), address);
516                        goto ERROR1;
517                }
518        }
519
520        /* Fill in remaining client fields and put it into the global list */
521        strcpy(new_client->name, "ASB100 chip");
522        data->type = kind;
523
524        data->valid = 0;
525        init_MUTEX(&data->update_lock);
526
527        /* Tell the I2C layer a new client has arrived */
528        if ((err = i2c_attach_client(new_client)))
529                goto ERROR1;
530
531        /* Attach secondary lm75 clients */
532        if ((err = asb100_detect_subclients(adapter, address, kind,
533                        new_client)))
534                goto ERROR2;
535
536        /* Initialize the chip */
537        asb100_init_client(new_client);
538
539        /* Register a new directory entry with module sensors */
540        if ((data->sysctl_id = i2c_register_entry(new_client, "asb100",
541                        asb100_dir_table_template, THIS_MODULE)) < 0) {
542                err = data->sysctl_id;
543                goto ERROR3;
544        }
545
546        return 0;
547
548ERROR3:
549        i2c_detach_client(data->lm75[0]);
550        kfree(data->lm75[1]);
551        kfree(data->lm75[0]);
552ERROR2:
553        i2c_detach_client(new_client);
554ERROR1:
555        kfree(data);
556ERROR0:
557        return err;
558}
559
560static int asb100_detach_client(struct i2c_client *client)
561{
562        int err;
563        struct asb100_data *data = client->data;
564
565        /* remove sysctl table (primary client only) */
566        if ((data))
567                i2c_deregister_entry(data->sysctl_id);
568
569        if ((err = i2c_detach_client(client))) {
570                printk (KERN_ERR "asb100.o: Client deregistration failed; "
571                        "client not detached.\n");
572                return err;
573        }
574
575        if (data) {
576                /* primary client */
577                kfree(data);
578        } else {
579                /* subclients */
580                kfree(client);
581        }
582
583        return 0;
584}
585
586/* The SMBus locks itself, usually, but nothing may access the Winbond between
587   bank switches. ISA access must always be locked explicitly!
588   We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
589   would slow down the W83781D access and should not be necessary.
590   There are some ugly typecasts here, but the good news is - they should
591   nowhere else be necessary! */
592static int asb100_read_value(struct i2c_client *client, u16 reg)
593{
594        struct asb100_data *data = client->data;
595        struct i2c_client *cl;
596        int res, bank;
597
598        down(&data->lock);
599
600        bank = (reg >> 8) & 0x0f;
601        if (bank > 2)
602                /* switch banks */
603                i2c_smbus_write_byte_data(client, ASB100_REG_BANK, bank);
604
605        if (bank == 0 || bank > 2) {
606                res = i2c_smbus_read_byte_data(client, reg & 0xff);
607        } else {
608                /* switch to subclient */
609                cl = data->lm75[bank - 1];
610
611                /* convert from ISA to LM75 I2C addresses */
612                switch (reg & 0xff) {
613                case 0x50: /* TEMP */
614                        res = swab16(i2c_smbus_read_word_data (cl, 0));
615                        break;
616                case 0x52: /* CONFIG */
617                        res = i2c_smbus_read_byte_data(cl, 1);
618                        break;
619                case 0x53: /* HYST */
620                        res = swab16(i2c_smbus_read_word_data (cl, 2));
621                        break;
622                case 0x55: /* MAX */
623                default:
624                        res = swab16(i2c_smbus_read_word_data (cl, 3));
625                        break;
626                }
627        }
628
629        if (bank > 2)
630                i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0);
631
632        up(&data->lock);
633
634        return res;
635}
636
637static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value)
638{
639        struct asb100_data *data = client->data;
640        struct i2c_client *cl;
641        int bank;
642
643        down(&data->lock);
644
645        bank = (reg >> 8) & 0x0f;
646        if (bank > 2)
647                /* switch banks */
648                i2c_smbus_write_byte_data(client, ASB100_REG_BANK, bank);
649
650        if (bank == 0 || bank > 2) {
651                i2c_smbus_write_byte_data(client, reg & 0xff, value & 0xff);
652        } else {
653                /* switch to subclient */
654                cl = data->lm75[bank - 1];
655
656                /* convert from ISA to LM75 I2C addresses */
657                switch (reg & 0xff) {
658                case 0x52: /* CONFIG */
659                        i2c_smbus_write_byte_data(cl, 1, value & 0xff);
660                        break;
661                case 0x53: /* HYST */
662                        i2c_smbus_write_word_data(cl, 2, swab16(value));
663                        break;
664                case 0x55: /* MAX */
665                        i2c_smbus_write_word_data(cl, 3, swab16(value));
666                        break;
667                }
668        }
669
670        if (bank > 2)
671                i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0);
672
673        up(&data->lock);
674}
675
676static void asb100_init_client(struct i2c_client *client)
677{
678        struct asb100_data *data = client->data;
679        int vid = 0;
680
681        vid = asb100_read_value(client, ASB100_REG_VID_FANDIV) & 0x0f;
682        vid |= (asb100_read_value(client, ASB100_REG_CHIPID) & 0x01) << 4;
683        data->vrm = ASB100_DEFAULT_VRM;
684        vid = vid_from_reg(vid, data->vrm);
685
686        /* Start monitoring */
687        asb100_write_value(client, ASB100_REG_CONFIG, 
688                (asb100_read_value(client, ASB100_REG_CONFIG) & 0xf7) | 0x01);
689}
690
691static void asb100_update_client(struct i2c_client *client)
692{
693        struct asb100_data *data = client->data;
694        int i;
695
696        down(&data->update_lock);
697
698        if (time_after(jiffies - data->last_updated, HZ + HZ / 2) ||
699                time_before(jiffies, data->last_updated) || !data->valid) {
700
701                pr_debug("asb100.o: starting device update...\n");
702
703                /* 7 voltage inputs */
704                for (i = 0; i < 7; i++) {
705                        data->in[i] = asb100_read_value(client,
706                                ASB100_REG_IN(i));
707                        data->in_min[i] = asb100_read_value(client,
708                                ASB100_REG_IN_MIN(i));
709                        data->in_max[i] = asb100_read_value(client,
710                                ASB100_REG_IN_MAX(i));
711                }
712
713                /* 3 fan inputs */
714                for (i = 1; i <= 3; i++) {
715                        data->fan[i-1] = asb100_read_value(client,
716                                        ASB100_REG_FAN(i));
717                        data->fan_min[i-1] = asb100_read_value(client,
718                                        ASB100_REG_FAN_MIN(i));
719                }
720
721                /* 4 temperature inputs */
722                for (i = 1; i <= 4; i++) {
723                        data->temp[i-1] = asb100_read_value(client,
724                                        ASB100_REG_TEMP(i));
725                        data->temp_max[i-1] = asb100_read_value(client,
726                                        ASB100_REG_TEMP_MAX(i));
727                        data->temp_hyst[i-1] = asb100_read_value(client,
728                                        ASB100_REG_TEMP_HYST(i));
729                }
730
731                /* VID and fan divisors */
732                i = asb100_read_value(client, ASB100_REG_VID_FANDIV);
733                data->vid = i & 0x0f;
734                data->vid |= (asb100_read_value(client,
735                                ASB100_REG_CHIPID) & 0x01) << 4;
736                data->fan_div[0] = (i >> 4) & 0x03;
737                data->fan_div[1] = (i >> 6) & 0x03;
738                data->fan_div[2] = (asb100_read_value(client,
739                                ASB100_REG_PIN) >> 6) & 0x03;
740
741                /* PWM */
742                data->pwm = asb100_read_value(client, ASB100_REG_PWM1);
743
744                /* alarms */
745                data->alarms = asb100_read_value(client, ASB100_REG_ALARM1) +
746                        (asb100_read_value(client, ASB100_REG_ALARM2) << 8);
747
748                data->last_updated = jiffies;
749                data->valid = 1;
750
751                pr_debug("asb100.o: ... update complete.\n");
752        }
753
754        up(&data->update_lock);
755}
756
757
758/* The next few functions are the call-back functions of the /proc/sys and
759   sysctl files. Which function is used is defined in the ctl_table in
760   the extra1 field.
761   Each function must return the magnitude (power of 10 to divide the date
762   with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must
763   put a maximum of *nrels elements in results reflecting the data of this
764   file, and set *nrels to the number it actually put in it, if operation==
765   SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from
766   results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE.
767   Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
768   large enough (by checking the incoming value of *nrels). This is not very
769   good practice, but as long as you put less than about 5 values in results,
770   you can assume it is large enough. */
771static void asb100_in(struct i2c_client *client, int operation, int ctl_name,
772               int *nrels_mag, long *results)
773{
774        struct asb100_data *data = client->data;
775        int nr = ctl_name - ASB100_SYSCTL_IN0;
776
777        if (operation == SENSORS_PROC_REAL_INFO)
778                *nrels_mag = 2;
779        else if (operation == SENSORS_PROC_REAL_READ) {
780                asb100_update_client(client);
781                results[0] = IN_FROM_REG(data->in_min[nr]);
782                results[1] = IN_FROM_REG(data->in_max[nr]);
783                results[2] = IN_FROM_REG(data->in[nr]);
784                *nrels_mag = 3;
785        } else if (operation == SENSORS_PROC_REAL_WRITE) {
786                if (*nrels_mag >= 1) {
787                        data->in_min[nr] = IN_TO_REG(results[0]);
788                        asb100_write_value(client, ASB100_REG_IN_MIN(nr),
789                                            data->in_min[nr]);
790                }
791                if (*nrels_mag >= 2) {
792                        data->in_max[nr] = IN_TO_REG(results[1]);
793                        asb100_write_value(client, ASB100_REG_IN_MAX(nr),
794                                            data->in_max[nr]);
795                }
796        }
797}
798
799void asb100_fan(struct i2c_client *client, int operation, int ctl_name,
800                 int *nrels_mag, long *results)
801{
802        struct asb100_data *data = client->data;
803        int nr = ctl_name - ASB100_SYSCTL_FAN1 + 1;
804
805        if (operation == SENSORS_PROC_REAL_INFO)
806                *nrels_mag = 0;
807        else if (operation == SENSORS_PROC_REAL_READ) {
808                asb100_update_client(client);
809                results[0] = FAN_FROM_REG(data->fan_min[nr - 1],
810                                  DIV_FROM_REG(data->fan_div[nr - 1]));
811                results[1] = FAN_FROM_REG(data->fan[nr - 1],
812                                  DIV_FROM_REG(data->fan_div[nr - 1]));
813                *nrels_mag = 2;
814        } else if (operation == SENSORS_PROC_REAL_WRITE) {
815                if (*nrels_mag >= 1) {
816                        data->fan_min[nr - 1] =
817                             FAN_TO_REG(results[0],
818                                    DIV_FROM_REG(data->fan_div[nr-1]));
819                        asb100_write_value(client,
820                                            ASB100_REG_FAN_MIN(nr),
821                                            data->fan_min[nr - 1]);
822                }
823        }
824}
825
826void asb100_temp(struct i2c_client *client, int operation, int ctl_name,
827                  int *nrels_mag, long *results)
828{
829        struct asb100_data *data = client->data;
830        int nr = ctl_name - ASB100_SYSCTL_TEMP1;
831
832        if (operation == SENSORS_PROC_REAL_INFO)
833                *nrels_mag = 1;
834
835        else if (operation == SENSORS_PROC_REAL_READ) {
836                asb100_update_client(client);
837                results[0] = TEMP_FROM_REG(data->temp_max[nr]);
838                results[1] = TEMP_FROM_REG(data->temp_hyst[nr]);
839                results[2] = TEMP_FROM_REG(data->temp[nr]);
840                *nrels_mag = 3;
841
842        } else if (operation == SENSORS_PROC_REAL_WRITE) {
843                if (*nrels_mag >= 1) {
844                        data->temp_max[nr] = TEMP_TO_REG(results[0]);
845                        asb100_write_value(client, ASB100_REG_TEMP_MAX(nr+1),
846                                data->temp_max[nr]);
847                }
848                if (*nrels_mag >= 2) {
849                        data->temp_hyst[nr] = TEMP_TO_REG(results[1]);
850                        asb100_write_value(client, ASB100_REG_TEMP_HYST(nr+1),
851                                data->temp_hyst[nr]);
852                }
853        }
854}
855
856void asb100_temp_add(struct i2c_client *client, int operation,
857                      int ctl_name, int *nrels_mag, long *results)
858{
859        struct asb100_data *data = client->data;
860        int nr = ctl_name - ASB100_SYSCTL_TEMP1;
861
862        if (operation == SENSORS_PROC_REAL_INFO)
863                *nrels_mag = 1;
864
865        else if (operation == SENSORS_PROC_REAL_READ) {
866                asb100_update_client(client);
867
868                results[0] = LM75_TEMP_FROM_REG(data->temp_max[nr]);
869                results[1] = LM75_TEMP_FROM_REG(data->temp_hyst[nr]);
870                results[2] = LM75_TEMP_FROM_REG(data->temp[nr]);
871                *nrels_mag = 3;
872
873        } else if (operation == SENSORS_PROC_REAL_WRITE) {
874                if (*nrels_mag >= 1) {
875                        data->temp_max[nr] =
876                                LM75_TEMP_TO_REG(results[0]);
877                        asb100_write_value(client, ASB100_REG_TEMP_MAX(nr+1),
878                                data->temp_max[nr]);
879                }
880                if (*nrels_mag >= 2) {
881                        data->temp_hyst[nr] =
882                                LM75_TEMP_TO_REG(results[1]);
883                        asb100_write_value(client, ASB100_REG_TEMP_HYST(nr+1),
884                                data->temp_hyst[nr]);
885                }
886        }
887}
888
889void asb100_vid(struct i2c_client *client, int operation, int ctl_name,
890                 int *nrels_mag, long *results)
891{
892        struct asb100_data *data = client->data;
893        if (operation == SENSORS_PROC_REAL_INFO)
894                *nrels_mag = 3;
895        else if (operation == SENSORS_PROC_REAL_READ) {
896                asb100_update_client(client);
897                results[0] = vid_from_reg(data->vid, data->vrm);
898                *nrels_mag = 1;
899        }
900}
901
902void asb100_vrm(struct i2c_client *client, int operation, int ctl_name,
903                 int *nrels_mag, long *results)
904{
905        struct asb100_data *data = client->data;
906        if (operation == SENSORS_PROC_REAL_INFO)
907                *nrels_mag = 1;
908        else if (operation == SENSORS_PROC_REAL_READ) {
909                results[0] = data->vrm;
910                *nrels_mag = 1;
911        } else if (operation == SENSORS_PROC_REAL_WRITE) {
912                if (*nrels_mag >= 1)
913                        data->vrm = results[0];
914        }
915}
916
917void asb100_alarms(struct i2c_client *client, int operation, int ctl_name,
918                    int *nrels_mag, long *results)
919{
920        struct asb100_data *data = client->data;
921        if (operation == SENSORS_PROC_REAL_INFO)
922                *nrels_mag = 0;
923        else if (operation == SENSORS_PROC_REAL_READ) {
924                asb100_update_client(client);
925                results[0] = ALARMS_FROM_REG(data->alarms);
926                *nrels_mag = 1;
927        }
928}
929
930void asb100_fan_div(struct i2c_client *client, int operation,
931                     int ctl_name, int *nrels_mag, long *results)
932{
933        struct asb100_data *data = client->data;
934        int old, old2;
935
936        if (operation == SENSORS_PROC_REAL_INFO)
937                *nrels_mag = 0;
938
939        else if (operation == SENSORS_PROC_REAL_READ) {
940                asb100_update_client(client);
941                results[0] = DIV_FROM_REG(data->fan_div[0]);
942                results[1] = DIV_FROM_REG(data->fan_div[1]);
943                results[2] = DIV_FROM_REG(data->fan_div[2]);
944                *nrels_mag = 3;
945
946        } else if (operation == SENSORS_PROC_REAL_WRITE) {
947                old = asb100_read_value(client, ASB100_REG_VID_FANDIV);
948                if (*nrels_mag >= 3) {
949                        data->fan_div[2] = DIV_TO_REG(results[2]);
950                        old2 = asb100_read_value(client, ASB100_REG_PIN);
951                        old2 = (old2 & 0x3f) | ((data->fan_div[2] & 0x03) << 6);
952                        asb100_write_value(client, ASB100_REG_PIN, old2);
953                }
954                if (*nrels_mag >= 2) {
955                        data->fan_div[1] = DIV_TO_REG(results[1]);
956                        old = (old & 0x3f) | ((data->fan_div[1] & 0x03) << 6);
957                }
958                if (*nrels_mag >= 1) {
959                        data->fan_div[0] = DIV_TO_REG(results[0]);
960                        old = (old & 0xcf) | ((data->fan_div[0] & 0x03) << 4);
961                        asb100_write_value(client, ASB100_REG_VID_FANDIV, old);
962                }
963        }
964}
965
966void asb100_pwm(struct i2c_client *client, int operation, int ctl_name,
967                int *nrels_mag, long *results)
968{
969        struct asb100_data *data = client->data;
970
971        if (operation == SENSORS_PROC_REAL_INFO)
972                *nrels_mag = 0;
973        else if (operation == SENSORS_PROC_REAL_READ) {
974                asb100_update_client(client);
975                results[0] = ASB100_PWM_FROM_REG(data->pwm & 0x0f);
976                results[1] = (data->pwm & 0x80) ? 1 : 0;
977                *nrels_mag = 2;
978        } else if (operation == SENSORS_PROC_REAL_WRITE) {
979                u8 val = data->pwm;
980                if (*nrels_mag >= 1) {
981                        val = 0x0f & ASB100_PWM_TO_REG(results[0]);
982                        if (*nrels_mag >= 2) {
983                                if (results[1])
984                                        val |= 0x80;
985                                else
986                                        val &= ~0x80;
987                        }
988                        asb100_write_value(client, ASB100_REG_PWM1, val);
989                }
990        }
991}
992
993static int __init asb100_init(void)
994{
995        printk(KERN_INFO "asb100.o version %s (%s)\n", LM_VERSION, LM_DATE);
996        return i2c_add_driver(&asb100_driver);
997}
998
999static void __exit asb100_exit(void)
1000{
1001        i2c_del_driver(&asb100_driver);
1002}
1003
1004MODULE_AUTHOR(  "Mark M. Hoffman <mhoffman@lightlink.com>, "
1005                "Frodo Looijaard <frodol@dds.nl>, "
1006                "Philip Edelbrock <phil@netroedge.com>, and "
1007                "Mark Studebaker <mdsxyz123@yahoo.com>");
1008
1009MODULE_DESCRIPTION("ASB100 'Bach' driver");
1010MODULE_LICENSE("GPL");
1011
1012module_init(asb100_init);
1013module_exit(asb100_exit);
1014
Note: See TracBrowser for help on using the browser.