Commit 62e88cfd authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/i2c-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 340de76c de2bd6e9
Revision 3, 2003-10-04 Revision 4, 2004-03-30
Jean Delvare <khali@linux-fr.org> Jean Delvare <khali@linux-fr.org>
Greg KH <greg@kroah.com> Greg KH <greg@kroah.com>
...@@ -24,9 +24,10 @@ Technical changes: ...@@ -24,9 +24,10 @@ Technical changes:
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> /* if you need VRM support */ #include <linux/i2c-vid.h> /* if you need VRM support */
#include <asm/io.h> /* if you have I/O operations */ #include <asm/io.h> /* if you have I/O operations */
Some extra headers may be required for a given driver. Please respect this inclusion order. Some extra headers may be
required for a given driver (e.g. "lm75.h").
* [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, SENSORS_ISA_END * [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, SENSORS_ISA_END
becomes I2C_CLIENT_ISA_END. becomes I2C_CLIENT_ISA_END.
...@@ -37,9 +38,9 @@ Technical changes: ...@@ -37,9 +38,9 @@ Technical changes:
names for sysfs files (see the Sysctl section below). names for sysfs files (see the Sysctl section below).
* [Function prototypes] The detect functions loses its flags * [Function prototypes] The detect functions loses its flags
parameter. Sysctl (e.g. lm75_temp) and miscellaneous (e.g. parameter. Sysctl (e.g. lm75_temp) and miscellaneous functions
swap_bytes) functions are off the list of prototypes. This are off the list of prototypes. This usually leaves five
usually leaves five prototypes: prototypes:
static int lm75_attach_adapter(struct i2c_adapter *adapter); static int lm75_attach_adapter(struct i2c_adapter *adapter);
static int lm75_detect(struct i2c_adapter *adapter, int address, static int lm75_detect(struct i2c_adapter *adapter, int address,
int kind); int kind);
...@@ -70,13 +71,14 @@ Technical changes: ...@@ -70,13 +71,14 @@ Technical changes:
* [Detect] As mentioned earlier, the flags parameter is gone. * [Detect] As mentioned earlier, the flags parameter is gone.
The type_name and client_name strings are replaced by a single The type_name and client_name strings are replaced by a single
name string, which will be filled with a lowercase, short string name string, which will be filled with a lowercase, short string
(typically the driver name, e.g. "lm75"). The errorN labels are (typically the driver name, e.g. "lm75").
reduced to the number needed. If that number is 2 (i2c-only In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
drivers), it is advised that the labels are named exit and useless.
exit_free. For i2c+isa drivers, labels should be named ERROR0, The errorN labels are reduced to the number needed. If that number
ERROR1 and ERROR2. Don't forget to properly set err before is 2 (i2c-only drivers), it is advised that the labels are named
jumping to error labels. By the way, labels should be exit and exit_free. For i2c+isa drivers, labels should be named
left-aligned. ERROR0, ERROR1 and ERROR2. Don't forget to properly set err before
jumping to error labels. By the way, labels should be left-aligned.
Use memset to fill the client and data area with 0x00. Use memset to fill the client and data area with 0x00.
Use i2c_set_clientdata to set the client data (as opposed to Use i2c_set_clientdata to set the client data (as opposed to
a direct access to client->data). a direct access to client->data).
...@@ -85,6 +87,11 @@ Technical changes: ...@@ -85,6 +87,11 @@ Technical changes:
device_create_file. Move the driver initialization before any device_create_file. Move the driver initialization before any
sysfs file creation. sysfs file creation.
* [Init] Limits must not be set by the driver (can be done later in
user-space). Chip should not be reset default (although a module
parameter may be used to force is), and initialization should be
limited to the strictly necessary steps.
* [Detach] Get rid of data, remove the call to * [Detach] Get rid of data, remove the call to
i2c_deregister_entry. i2c_deregister_entry.
...@@ -92,7 +99,8 @@ Technical changes: ...@@ -92,7 +99,8 @@ Technical changes:
i2c_get_clientdata(client) instead. i2c_get_clientdata(client) instead.
* [Interface] Init function should not print anything. Make sure * [Interface] Init function should not print anything. Make sure
there is a MODULE_LICENSE() line. there is a MODULE_LICENSE() line, at the bottom of the file
(after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this order).
Coding policy: Coding policy:
...@@ -102,8 +110,7 @@ Coding policy: ...@@ -102,8 +110,7 @@ Coding policy:
can. Calls to printk/pr_debug for debugging purposes are replaced can. Calls to printk/pr_debug for debugging purposes are replaced
by calls to dev_dbg. Here is an example on how to call it (taken by calls to dev_dbg. Here is an example on how to call it (taken
from lm75_detect): from lm75_detect):
dev_dbg(&adapter->dev, dev_dbg(&client->dev, "Starting lm75 update\n");
"lm75_detect called for an ISA bus adapter?!?\n");
Replace other printk calls with the dev_info, dev_err or dev_warn Replace other printk calls with the dev_info, dev_err or dev_warn
function, as appropriate. function, as appropriate.
...@@ -119,3 +126,8 @@ Coding policy: ...@@ -119,3 +126,8 @@ Coding policy:
* [Layout] Avoid extra empty lines between comments and what they * [Layout] Avoid extra empty lines between comments and what they
comment. Respect the coding style (see Documentation/CodingStyle), comment. Respect the coding style (see Documentation/CodingStyle),
in particular when it comes to placing curly braces. in particular when it comes to placing curly braces.
* [Comments] Make sure that no comment refers to a file that isn't
part of the Linux source tree (typically doc/chips/<chip name>),
and that remaining comments still match the code. Merging comment
lines when possible is encouraged.
...@@ -74,18 +74,15 @@ to cause an alarm) is chip-dependent. ...@@ -74,18 +74,15 @@ to cause an alarm) is chip-dependent.
************ ************
in[0-8]_min Voltage min value. in[0-8]_min Voltage min value.
Fixed point value in form XXXX. Divide by 1000 to get Unit: millivolt
Volts.
Read/Write Read/Write
in[0-8]_max Voltage max value. in[0-8]_max Voltage max value.
Fixed point value in form XXXX. Divide by 1000 to get Unit: millivolt
Volts.
Read/Write Read/Write
in[0-8]_input Voltage input value. in[0-8]_input Voltage input value.
Fixed point value in form XXXX. Divide by 1000 to get Unit: millivolt
Volts.
Read only Read only
Actual voltage depends on the scaling resistors on the Actual voltage depends on the scaling resistors on the
motherboard, as recommended in the chip datasheet. motherboard, as recommended in the chip datasheet.
...@@ -95,10 +92,10 @@ in[0-8]_input Voltage input value. ...@@ -95,10 +92,10 @@ in[0-8]_input Voltage input value.
However, some drivers (notably lm87 and via686a) However, some drivers (notably lm87 and via686a)
do scale, with various degrees of success. do scale, with various degrees of success.
These drivers will output the actual voltage. These drivers will output the actual voltage.
First two values are read/write and third is read only.
Typical usage: Typical usage:
in0_* CPU #1 voltage (not scaled) in0_* CPU #1 voltage (not scaled)
in1_* CPU #1 voltage (not scaled) in1_* CPU #2 voltage (not scaled)
in2_* 3.3V nominal (not scaled) in2_* 3.3V nominal (not scaled)
in3_* 5.0V nominal (scaled) in3_* 5.0V nominal (scaled)
in4_* 12.0V nominal (scaled) in4_* 12.0V nominal (scaled)
...@@ -108,17 +105,16 @@ in[0-8]_input Voltage input value. ...@@ -108,17 +105,16 @@ in[0-8]_input Voltage input value.
in8_* varies in8_* varies
in0_ref CPU core reference voltage. in0_ref CPU core reference voltage.
Unit: millivolt
Read only. Read only.
Fixed point value in form XXXX corresponding to CPU core Not always correct.
voltage as told to the sensor chip. Divide by 1000 to
get Volts. Not always correct.
vrm Voltage Regulator Module version number. vrm Voltage Regulator Module version number.
Read only. Read only.
Two digit number (XX), first is major version, second is Two digit number, first is major version, second is
minor version. minor version.
Affects the way the driver calculates the core voltage from Affects the way the driver calculates the CPU core reference
the vid pins. See doc/vid for details. voltage from the vid pins.
******** ********
...@@ -126,23 +122,23 @@ vrm Voltage Regulator Module version number. ...@@ -126,23 +122,23 @@ vrm Voltage Regulator Module version number.
******** ********
fan[1-3]_min Fan minimum value fan[1-3]_min Fan minimum value
Integer value indicating RPM Unit: revolution/min (RPM)
Read/Write. Read/Write.
fan[1-3]_input Fan input value. fan[1-3]_input Fan input value.
Integer value indicating RPM Unit: revolution/min (RPM)
Read only. Read only.
fan[1-3]_div Fan divisor. fan[1-3]_div Fan divisor.
Integers in powers of two (1,2,4,8,16,32,64,128). Integer value in powers of two (1, 2, 4, 8, 16, 32, 64, 128).
Some chips only support values 1,2,4,8. Some chips only support values 1, 2, 4 and 8.
See doc/fan-divisors for details. Note that this is actually an internal clock divisor, which
affects the measurable speed range, not the read value.
fan[1-3]_pwm Pulse width modulation fan control. fan[1-3]_pwm Pulse width modulation fan control.
Integer 0 - 255 Integer value in the range 0 to 255
Read/Write Read/Write
255 is max or 100%. 255 is max or 100%.
Corresponds to the fans 1-3.
fan[1-3]_pwm_enable fan[1-3]_pwm_enable
Switch PWM on and off. Switch PWM on and off.
...@@ -157,46 +153,46 @@ fan[1-3]_pwm_enable ...@@ -157,46 +153,46 @@ fan[1-3]_pwm_enable
**************** ****************
temp[1-3]_type Sensor type selection. temp[1-3]_type Sensor type selection.
Integers 1,2,3, or thermistor Beta value (3435) Integers 1, 2, 3 or thermistor Beta value (3435)
Read/Write. Read/Write.
1: PII/Celeron Diode
2: 3904 transistor
3: thermal diode
Not all types are supported by all chips
temp[1-4]_max Temperature max value. temp[1-4]_max Temperature max value.
Fixed point value in form XXXXX and should be divided by Unit: millidegree Celcius
1000 to get degrees Celsius.
Read/Write value. Read/Write value.
temp[1-3]_min Temperature min value. temp[1-3]_min Temperature min value.
Fixed point value in form XXXXX and should be divided by Unit: millidegree Celcius
1000 to get degrees Celsius.
Read/Write value. Read/Write value.
temp[1-3]_max_hyst temp[1-3]_max_hyst
Temperature hysteresis value for max limit. Temperature hysteresis value for max limit.
Fixed point value in form XXXXX and should be divided by Unit: millidegree Celcius
1000 to get degrees Celsius. Must be reported as an Must be reported as an absolute temperature, NOT a delta
absolute temperature, NOT a delta from the max value. from the max value.
Read/Write value. Read/Write value.
temp[1-4]_input Temperature input value. temp[1-4]_input Temperature input value.
Fixed point value in form XXXXX and should be divided by Unit: millidegree Celcius
1000 to get degrees Celsius.
Read only value. Read only value.
temp[1-4]_crit Temperature critical value, typically greater than temp[1-4]_crit Temperature critical value, typically greater than
corresponding temp_max values. corresponding temp_max values.
Fixed point value in form XXXXX and should be divided by Unit: millidegree Celcius
1000 to get degrees Celsius.
Read/Write value. Read/Write value.
temp[1-2]_crit_hyst temp[1-2]_crit_hyst
Temperature hysteresis value for critical limit. Temperature hysteresis value for critical limit.
Fixed point value in form XXXXX and should be divided by Unit: millidegree Celcius
1000 to get degrees Celsius. Must be reported as an Must be reported as an absolute temperature, NOT a delta
absolute temperature, NOT a delta from the critical value. from the critical value.
Read/Write value. Read/Write value.
If there are multiple temperature sensors, temp1_* is If there are multiple temperature sensors, temp1_* is
generally the sensor inside the chip itself, generally generally the sensor inside the chip itself,
reported as "motherboard temperature". temp2_* to reported as "motherboard temperature". temp2_* to
temp4_* are generally sensors external to the chip temp4_* are generally sensors external to the chip
itself, for example the thermal diode inside the CPU or itself, for example the thermal diode inside the CPU or
...@@ -211,15 +207,15 @@ Note that no known chip provides current measurements as of writing, ...@@ -211,15 +207,15 @@ Note that no known chip provides current measurements as of writing,
so this part is theoretical, so to say. so this part is theoretical, so to say.
curr[1-n]_max Current max value curr[1-n]_max Current max value
Fixed point XXXXX, divide by 1000 to get Amps. Unit: milliampere
Read/Write. Read/Write.
curr[1-n]_min Current min value. curr[1-n]_min Current min value.
Fixed point XXXXX, divide by 1000 to get Amps. Unit: milliampere
Read/Write. Read/Write.
curr[1-n]_input Current input value curr[1-n]_input Current input value
Fixed point XXXXX, divide by 1000 to get Amps. Unit: milliampere
Read only. Read only.
...@@ -246,7 +242,7 @@ beep_enable Beep/interrupt enable ...@@ -246,7 +242,7 @@ beep_enable Beep/interrupt enable
beep_mask Bitmask for beep. beep_mask Bitmask for beep.
Same format as 'alarms' with the same bit locations. Same format as 'alarms' with the same bit locations.
Read only. Read/Write
eeprom Raw EEPROM data in binary form. eeprom Raw EEPROM data in binary form.
Read only. Read only.
...@@ -591,12 +591,13 @@ static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, ...@@ -591,12 +591,13 @@ static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router,
{ {
switch(device) switch(device)
{ {
case PCI_DEVICE_ID_AL_M1533: case PCI_DEVICE_ID_AL_M1533:
case PCI_DEVICE_ID_AL_M1563:
printk("PCI: Using ALI IRQ Router\n");
r->name = "ALI"; r->name = "ALI";
r->get = pirq_ali_get; r->get = pirq_ali_get;
r->set = pirq_ali_set; r->set = pirq_ali_set;
return 1; return 1;
/* Should add 156x some day */
} }
return 0; return 0;
} }
......
...@@ -17,6 +17,18 @@ config I2C_ALI1535 ...@@ -17,6 +17,18 @@ config I2C_ALI1535
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-ali1535. will be called i2c-ali1535.
config I2C_ALI1563
tristate "ALI 1563"
depends on I2C && PCI && EXPERIMENTAL
help
If you say yes to this option, support will be included for the SMB
Host controller on Acer Labs Inc. (ALI) M1563 South Bridges. The SMB
controller is part of the 7101 device, which is an ACPI-compliant
Power Management Unit (PMU).
This driver can also be built as a module. If so, the module
will be called i2c-ali1563.
config I2C_ALI15X3 config I2C_ALI15X3
tristate "ALI 15x3" tristate "ALI 15x3"
depends on I2C && PCI && EXPERIMENTAL depends on I2C && PCI && EXPERIMENTAL
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# #
obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o
obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o
obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o
obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o
obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
......
/**
* i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge
*
* Copyright (C) 2004 Patrick Mochel
*
* The 1563 southbridge is deceptively similar to the 1533, with a
* few notable exceptions. One of those happens to be the fact they
* upgraded the i2c core to be 2.0 compliant, and happens to be almost
* identical to the i2c controller found in the Intel 801 south
* bridges.
*
* This driver is based on a mix of the 15x3, 1535, and i801 drivers,
* with a little help from the ALi 1563 spec.
*
* This file is released under the GPLv2
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/pci.h>
#include <linux/init.h>
#define ALI1563_MAX_TIMEOUT 500
#define ALI1563_SMBBA 0x80
#define ALI1563_SMB_IOEN 1
#define ALI1563_SMB_HOSTEN 2
#define ALI1563_SMB_IOSIZE 16
#define SMB_HST_STS (ali1563_smba + 0)
#define SMB_HST_CNTL1 (ali1563_smba + 1)
#define SMB_HST_CNTL2 (ali1563_smba + 2)
#define SMB_HST_CMD (ali1563_smba + 3)
#define SMB_HST_ADD (ali1563_smba + 4)
#define SMB_HST_DAT0 (ali1563_smba + 5)
#define SMB_HST_DAT1 (ali1563_smba + 6)
#define SMB_BLK_DAT (ali1563_smba + 7)
#define HST_STS_BUSY 0x01
#define HST_STS_INTR 0x02
#define HST_STS_DEVERR 0x04
#define HST_STS_BUSERR 0x08
#define HST_STS_FAIL 0x10
#define HST_STS_DONE 0x80
#define HST_STS_BAD 0x1c
#define HST_CNTL1_TIMEOUT 0x80
#define HST_CNTL1_LAST 0x40
#define HST_CNTL2_KILL 0x04
#define HST_CNTL2_START 0x40
#define HST_CNTL2_QUICK 0x00
#define HST_CNTL2_BYTE 0x01
#define HST_CNTL2_BYTE_DATA 0x02
#define HST_CNTL2_WORD_DATA 0x03
#define HST_CNTL2_BLOCK 0x05
static unsigned short ali1563_smba;
static int ali1563_transaction(struct i2c_adapter * a)
{
u32 data;
int timeout;
dev_dbg(&a->dev, "Transaction (pre): STS=%02x, CNTL1=%02x, "
"CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
inb_p(SMB_HST_STS), inb_p(SMB_HST_CNTL1), inb_p(SMB_HST_CNTL2),
inb_p(SMB_HST_CMD), inb_p(SMB_HST_ADD), inb_p(SMB_HST_DAT0),
inb_p(SMB_HST_DAT1));
data = inb_p(SMB_HST_STS);
if (data & HST_STS_BAD) {
dev_warn(&a->dev,"ali1563: Trying to reset busy device\n");
outb_p(data | HST_STS_BAD,SMB_HST_STS);
data = inb_p(SMB_HST_STS);
if (data & HST_STS_BAD)
return -EBUSY;
}
outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_START, SMB_HST_CNTL2);
timeout = ALI1563_MAX_TIMEOUT;
do
i2c_delay(1);
while (((data = inb_p(SMB_HST_STS)) & HST_STS_BUSY) && --timeout);
dev_dbg(&a->dev, "Transaction (post): STS=%02x, CNTL1=%02x, "
"CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
inb_p(SMB_HST_STS), inb_p(SMB_HST_CNTL1), inb_p(SMB_HST_CNTL2),
inb_p(SMB_HST_CMD), inb_p(SMB_HST_ADD), inb_p(SMB_HST_DAT0),
inb_p(SMB_HST_DAT1));
if (timeout && !(data & HST_STS_BAD))
return 0;
dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n",
timeout ? "Timeout " : "",
data & HST_STS_FAIL ? "Transaction Failed " : "",
data & HST_STS_BUSERR ? "No response or Bus Collision " : "",
data & HST_STS_DEVERR ? "Device Error " : "",
!(data & HST_STS_DONE) ? "Transaction Never Finished " : "");
if (!(data & HST_STS_DONE))
/* Issue 'kill' to host controller */
outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2);
else
/* Issue timeout to reset all devices on bus */
outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1);
return -1;
}
static int ali1563_block_start(struct i2c_adapter * a)
{
u32 data;
int timeout;
dev_dbg(&a->dev, "Block (pre): STS=%02x, CNTL1=%02x, "
"CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
inb_p(SMB_HST_STS), inb_p(SMB_HST_CNTL1), inb_p(SMB_HST_CNTL2),
inb_p(SMB_HST_CMD), inb_p(SMB_HST_ADD), inb_p(SMB_HST_DAT0),
inb_p(SMB_HST_DAT1));
data = inb_p(SMB_HST_STS);
if (data & HST_STS_BAD) {
dev_warn(&a->dev,"ali1563: Trying to reset busy device\n");
outb_p(data | HST_STS_BAD,SMB_HST_STS);
data = inb_p(SMB_HST_STS);
if (data & HST_STS_BAD)
return -EBUSY;
}
/* Clear byte-ready bit */
outb_p(data | HST_STS_DONE, SMB_HST_STS);
/* Start transaction and wait for byte-ready bit to be set */
outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_START, SMB_HST_CNTL2);
timeout = ALI1563_MAX_TIMEOUT;
do
i2c_delay(1);
while (!((data = inb_p(SMB_HST_STS)) & HST_STS_DONE) && --timeout);
dev_dbg(&a->dev, "Block (post): STS=%02x, CNTL1=%02x, "
"CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
inb_p(SMB_HST_STS), inb_p(SMB_HST_CNTL1), inb_p(SMB_HST_CNTL2),
inb_p(SMB_HST_CMD), inb_p(SMB_HST_ADD), inb_p(SMB_HST_DAT0),
inb_p(SMB_HST_DAT1));
if (timeout && !(data & HST_STS_BAD))
return 0;
dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n",
timeout ? "Timeout " : "",
data & HST_STS_FAIL ? "Transaction Failed " : "",
data & HST_STS_BUSERR ? "No response or Bus Collision " : "",
data & HST_STS_DEVERR ? "Device Error " : "",
!(data & HST_STS_DONE) ? "Transaction Never Finished " : "");
return -1;
}
static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8 rw)
{
int i, len;
int error = 0;
/* Do we need this? */
outb_p(HST_CNTL1_LAST,SMB_HST_CNTL1);
if (rw == I2C_SMBUS_WRITE) {
len = data->block[0];
if (len < 1)
len = 1;
else if (len > 32)
len = 32;
outb_p(len,SMB_HST_DAT0);
outb_p(data->block[1],SMB_BLK_DAT);
} else
len = 32;
outb_p(inb_p(SMB_HST_CNTL2) | HST_CNTL2_BLOCK, SMB_HST_CNTL2);
for (i = 0; i < len; i++) {
if (rw == I2C_SMBUS_WRITE) {
outb_p(data->block[i + 1], SMB_BLK_DAT);
if ((error = ali1563_block_start(a)))
break;
} else {
if ((error = ali1563_block_start(a)))
break;
if (i == 0) {
len = inb_p(SMB_HST_DAT0);
if (len < 1)
len = 1;
else if (len > 32)
len = 32;
}
data->block[i+1] = inb_p(SMB_BLK_DAT);
}
}
/* Do we need this? */
outb_p(HST_CNTL1_LAST,SMB_HST_CNTL1);
return error;
}
static s32 ali1563_access(struct i2c_adapter * a, u16 addr,
unsigned short flags, char rw, u8 cmd,
int size, union i2c_smbus_data * data)
{
int error = 0;
int timeout;
u32 reg;
for (timeout = ALI1563_MAX_TIMEOUT; timeout; timeout--) {
if (!(reg = inb_p(SMB_HST_STS) & HST_STS_BUSY))
break;
}
if (!timeout)
dev_warn(&a->dev,"SMBus not idle. HST_STS = %02x\n",reg);
outb_p(0xff,SMB_HST_STS);
/* Map the size to what the chip understands */
switch (size) {
case I2C_SMBUS_PROC_CALL:
dev_err(&a->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
error = -EINVAL;
break;
case I2C_SMBUS_QUICK:
size = HST_CNTL2_QUICK;
break;
case I2C_SMBUS_BYTE:
size = HST_CNTL2_BYTE;
break;
case I2C_SMBUS_BYTE_DATA:
size = HST_CNTL2_BYTE_DATA;
break;
case I2C_SMBUS_WORD_DATA:
size = HST_CNTL2_WORD_DATA;
break;
case I2C_SMBUS_BLOCK_DATA:
size = HST_CNTL2_BLOCK;
break;
}
outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD);
outb_p(inb_p(SMB_HST_CNTL2) | (size << 3), SMB_HST_CNTL2);
/* Write the command register */
switch(size) {
case HST_CNTL2_BYTE:
if (rw== I2C_SMBUS_WRITE)
outb_p(cmd, SMB_HST_CMD);
break;
case HST_CNTL2_BYTE_DATA:
outb_p(cmd, SMB_HST_CMD);
if (rw == I2C_SMBUS_WRITE)
outb_p(data->byte, SMB_HST_DAT0);
break;
case HST_CNTL2_WORD_DATA:
outb_p(cmd, SMB_HST_CMD);
if (rw == I2C_SMBUS_WRITE) {
outb_p(data->word & 0xff, SMB_HST_DAT0);
outb_p((data->word & 0xff00) >> 8, SMB_HST_DAT1);
}
break;
case HST_CNTL2_BLOCK:
outb_p(cmd, SMB_HST_CMD);
error = ali1563_block(a,data,rw);
goto Done;
}
if ((error = ali1563_transaction(a)))
goto Done;
if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK))
goto Done;
switch (size) {
case HST_CNTL2_BYTE: /* Result put in SMBHSTDAT0 */
data->byte = inb_p(SMB_HST_DAT0);
break;
case HST_CNTL2_BYTE_DATA:
data->byte = inb_p(SMB_HST_DAT0);
break;
case HST_CNTL2_WORD_DATA:
data->word = inb_p(SMB_HST_DAT0) + (inb_p(SMB_HST_DAT1) << 8);
break;
}
Done:
return error;
}
static u32 ali1563_func(struct i2c_adapter * a)
{
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA;
}
static void ali1563_enable(struct pci_dev * dev)
{
u16 ctrl;
pci_read_config_word(dev,ALI1563_SMBBA,&ctrl);
ctrl |= 0x7;
pci_write_config_word(dev,ALI1563_SMBBA,ctrl);
}
static int __init ali1563_setup(struct pci_dev * dev)
{
u16 ctrl;
pci_read_config_word(dev,ALI1563_SMBBA,&ctrl);
printk("ali1563: SMBus control = %04x\n",ctrl);
/* Check if device is even enabled first */
if (!(ctrl & ALI1563_SMB_IOEN)) {
dev_warn(&dev->dev,"I/O space not enabled, trying manually\n");
ali1563_enable(dev);
}
if (!(ctrl & ALI1563_SMB_IOEN)) {
dev_warn(&dev->dev,"I/O space still not enabled, giving up\n");
goto Err;
}
if (!(ctrl & ALI1563_SMB_HOSTEN)) {
dev_warn(&dev->dev,"Host Controller not enabled\n");
goto Err;
}
/* SMB I/O Base in high 12 bits and must be aligned with the
* size of the I/O space. */
ali1563_smba = ctrl & ~(ALI1563_SMB_IOSIZE - 1);
if (!ali1563_smba) {
dev_warn(&dev->dev,"ali1563_smba Uninitialized\n");
goto Err;
}
if (!request_region(ali1563_smba,ALI1563_SMB_IOSIZE,"i2c-ali1563")) {
dev_warn(&dev->dev,"Could not allocate I/O space");
goto Err;
}
return 0;
Err:
return -ENODEV;
}
static void ali1563_shutdown(struct pci_dev *dev)
{
release_region(ali1563_smba,ALI1563_SMB_IOSIZE);
}
static struct i2c_algorithm ali1563_algorithm = {
.name = "Non-i2c SMBus adapter",
.id = I2C_ALGO_SMBUS,
.smbus_xfer = ali1563_access,
.functionality = ali1563_func,
};
static struct i2c_adapter ali1563_adapter = {
.owner = THIS_MODULE,
.class = I2C_ADAP_CLASS_SMBUS,
.algo = &ali1563_algorithm,
};
static int __init ali1563_probe(struct pci_dev * dev,
const struct pci_device_id * id_table)
{
int error;
if ((error = ali1563_setup(dev)))
return error;
ali1563_adapter.dev.parent = &dev->dev;
sprintf(ali1563_adapter.name,"SMBus ALi 1563 Adapter @ %04x",
ali1563_smba);
if ((error = i2c_add_adapter(&ali1563_adapter)))
ali1563_shutdown(dev);
printk("%s: Returning %d\n",__FUNCTION__,error);
return error;
}
static void __exit ali1563_remove(struct pci_dev * dev)
{
i2c_del_adapter(&ali1563_adapter);
ali1563_shutdown(dev);
}
static struct pci_device_id __devinitdata ali1563_id_table[] = {
{
.vendor = PCI_VENDOR_ID_AL,
.device = PCI_DEVICE_ID_AL_M1563,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{},
};
static struct pci_driver ali1563_pci_driver = {
.name = "i2c-ali1563",
.id_table = ali1563_id_table,
.probe = ali1563_probe,
.remove = ali1563_remove,
};
static int __init ali1563_init(void)
{
return pci_module_init(&ali1563_pci_driver);
}
module_init(ali1563_init);
static void __exit ali1563_exit(void)
{
pci_unregister_driver(&ali1563_pci_driver);
}
module_exit(ali1563_exit);
MODULE_LICENSE("GPL");
...@@ -209,4 +209,25 @@ config SENSORS_EEPROM ...@@ -209,4 +209,25 @@ config SENSORS_EEPROM
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called eeprom. will be called eeprom.
config SENSORS_PCF8574
tristate "Philips PCF8574 and PCF8574A"
depends on I2C && EXPERIMENTAL
select I2C_SENSOR
help
If you say yes here you get support for Philips PCF8574 and
PCF8574A chips.
This driver can also be built as a module. If so, the module
will be called pcf8574.
config SENSORS_PCF8591
tristate "Philips PCF8591"
depends on I2C && EXPERIMENTAL
select I2C_SENSOR
help
If you say yes here you get support for Philips PCF8591 chips.
This driver can also be built as a module. If so, the module
will be called pcf8591.
endmenu endmenu
...@@ -19,6 +19,8 @@ obj-$(CONFIG_SENSORS_LM80) += lm80.o ...@@ -19,6 +19,8 @@ obj-$(CONFIG_SENSORS_LM80) += lm80.o
obj-$(CONFIG_SENSORS_LM83) += lm83.o obj-$(CONFIG_SENSORS_LM83) += lm83.o
obj-$(CONFIG_SENSORS_LM85) += lm85.o obj-$(CONFIG_SENSORS_LM85) += lm85.o
obj-$(CONFIG_SENSORS_LM90) += lm90.o obj-$(CONFIG_SENSORS_LM90) += lm90.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
......
...@@ -98,13 +98,10 @@ SENSORS_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1 ...@@ -98,13 +98,10 @@ SENSORS_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1
they don't quite work like a thermostat the way the LM75 does. I.e., they don't quite work like a thermostat the way the LM75 does. I.e.,
a lower temp than THYST actually triggers an alarm instead of a lower temp than THYST actually triggers an alarm instead of
clearing it. Weird, ey? --Phil */ clearing it. Weird, ey? --Phil */
#define adm1021_INIT_TOS 60
#define adm1021_INIT_THYST 20
#define adm1021_INIT_REMOTE_TOS 60
#define adm1021_INIT_REMOTE_THYST 20
/* Each client has this additional data */ /* Each client has this additional data */
struct adm1021_data { struct adm1021_data {
struct i2c_client client;
enum chips type; enum chips type;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -151,9 +148,6 @@ static struct i2c_driver adm1021_driver = { ...@@ -151,9 +148,6 @@ static struct i2c_driver adm1021_driver = {
.detach_client = adm1021_detach_client, .detach_client = adm1021_detach_client,
}; };
/* I choose here for semi-static allocation. Complete dynamic
allocation could also be used; the code needed for this would probably
take more memory than the datastructure takes now. */
static int adm1021_id = 0; static int adm1021_id = 0;
#define show(value) \ #define show(value) \
...@@ -235,16 +229,13 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -235,16 +229,13 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access adm1021_{read,write}_value. */ But it allows us to access adm1021_{read,write}_value. */
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
sizeof(struct adm1021_data),
GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto error0; goto error0;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct adm1021_data));
sizeof(struct adm1021_data));
data = (struct adm1021_data *) (new_client + 1); new_client = &data->client;
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -253,8 +244,12 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -253,8 +244,12 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
/* Now, we do the remaining detection. */ /* Now, we do the remaining detection. */
if (kind < 0) { if (kind < 0) {
if ((adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0x03) != 0x00) if ((adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0x03) != 0x00
|| (adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x3F) != 0x00
|| (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) & 0xF8) != 0x00) {
err = -ENODEV;
goto error1; goto error1;
}
} }
/* Determine the chip type. */ /* Determine the chip type. */
...@@ -272,11 +267,14 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -272,11 +267,14 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
else if ((i == 0x4d) && else if ((i == 0x4d) &&
(adm1021_read_value(new_client, ADM1021_REG_DEV_ID) == 0x01)) (adm1021_read_value(new_client, ADM1021_REG_DEV_ID) == 0x01))
kind = max1617a; kind = max1617a;
/* LM84 Mfr ID in a different place */
else if (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) == 0x00)
kind = lm84;
else if (i == 0x54) else if (i == 0x54)
kind = mc1066; kind = mc1066;
/* LM84 Mfr ID in a different place, and it has more unused bits */
else if (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) == 0x00
&& (kind == 0 /* skip extra detection */
|| ((adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x7F) == 0x00
&& (adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0xAB) == 0x00)))
kind = lm84;
else else
kind = max1617; kind = max1617;
} }
...@@ -309,10 +307,11 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -309,10 +307,11 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
/* Tell the I2C layer a new client has arrived */ /* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto error3; goto error1;
/* Initialize the ADM1021 chip */ /* Initialize the ADM1021 chip */
adm1021_init_client(new_client); if (kind != lm84)
adm1021_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_temp1_max); device_create_file(&new_client->dev, &dev_attr_temp1_max);
...@@ -327,26 +326,17 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -327,26 +326,17 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
error3:
error1: error1:
kfree(new_client); kfree(data);
error0: error0:
return err; return err;
} }
static void adm1021_init_client(struct i2c_client *client) static void adm1021_init_client(struct i2c_client *client)
{ {
/* Initialize the adm1021 chip */
adm1021_write_value(client, ADM1021_REG_TOS_W,
adm1021_INIT_TOS);
adm1021_write_value(client, ADM1021_REG_THYST_W,
adm1021_INIT_THYST);
adm1021_write_value(client, ADM1021_REG_REMOTE_TOS_W,
adm1021_INIT_REMOTE_TOS);
adm1021_write_value(client, ADM1021_REG_REMOTE_THYST_W,
adm1021_INIT_REMOTE_THYST);
/* Enable ADC and disable suspend mode */ /* Enable ADC and disable suspend mode */
adm1021_write_value(client, ADM1021_REG_CONFIG_W, 0); adm1021_write_value(client, ADM1021_REG_CONFIG_W,
adm1021_read_value(client, ADM1021_REG_CONFIG_R) & 0xBF);
/* Set Conversion rate to 1/sec (this can be tinkered with) */ /* Set Conversion rate to 1/sec (this can be tinkered with) */
adm1021_write_value(client, ADM1021_REG_CONV_RATE_W, 0x04); adm1021_write_value(client, ADM1021_REG_CONV_RATE_W, 0x04);
} }
...@@ -360,7 +350,7 @@ static int adm1021_detach_client(struct i2c_client *client) ...@@ -360,7 +350,7 @@ static int adm1021_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
...@@ -124,7 +124,7 @@ static const u16 asb100_reg_temp_hyst[] = {0, 0x3a, 0x153, 0x253, 0x19}; ...@@ -124,7 +124,7 @@ static const u16 asb100_reg_temp_hyst[] = {0, 0x3a, 0x153, 0x253, 0x19};
static u8 IN_TO_REG(unsigned val) static u8 IN_TO_REG(unsigned val)
{ {
unsigned nval = SENSORS_LIMIT(val, ASB100_IN_MIN, ASB100_IN_MAX); unsigned nval = SENSORS_LIMIT(val, ASB100_IN_MIN, ASB100_IN_MAX);
return nval / 16; return (nval + 8) / 16;
} }
static unsigned IN_FROM_REG(u8 reg) static unsigned IN_FROM_REG(u8 reg)
...@@ -193,6 +193,7 @@ static u8 DIV_TO_REG(long val) ...@@ -193,6 +193,7 @@ static u8 DIV_TO_REG(long val)
data is pointed to by client->data. The structure itself is data is pointed to by client->data. The structure itself is
dynamically allocated, at the same time the client itself is allocated. */ dynamically allocated, at the same time the client itself is allocated. */
struct asb100_data { struct asb100_data {
struct i2c_client client;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -467,7 +468,7 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \ ...@@ -467,7 +468,7 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \
data->reg[nr] = TEMP_TO_REG(val); \ data->reg[nr] = TEMP_TO_REG(val); \
break; \ break; \
} \ } \
asb100_write_value(client, ASB100_REG_TEMP_##REG(nr), \ asb100_write_value(client, ASB100_REG_TEMP_##REG(nr+1), \
data->reg[nr]); \ data->reg[nr]); \
return count; \ return count; \
} }
...@@ -722,17 +723,14 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -722,17 +723,14 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access asb100_{read,write}_value. */ But it allows us to access asb100_{read,write}_value. */
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct asb100_data), GFP_KERNEL))) {
sizeof(struct asb100_data), GFP_KERNEL))) {
pr_debug("asb100.o: detect failed, kmalloc failed!\n"); pr_debug("asb100.o: detect failed, kmalloc failed!\n");
err = -ENOMEM; err = -ENOMEM;
goto ERROR0; goto ERROR0;
} }
memset(data, 0, sizeof(struct asb100_data));
memset(new_client, 0, new_client = &data->client;
sizeof(struct i2c_client) + sizeof(struct asb100_data));
data = (struct asb100_data *) (new_client + 1);
init_MUTEX(&data->lock); init_MUTEX(&data->lock);
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
...@@ -807,6 +805,11 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -807,6 +805,11 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
/* Initialize the chip */ /* Initialize the chip */
asb100_init_client(new_client); asb100_init_client(new_client);
/* A few vars need to be filled upon startup */
data->fan_min[0] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(0));
data->fan_min[1] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(1));
data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2));
/* Register sysfs hooks */ /* Register sysfs hooks */
device_create_file_in(new_client, 0); device_create_file_in(new_client, 0);
device_create_file_in(new_client, 1); device_create_file_in(new_client, 1);
...@@ -837,7 +840,7 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -837,7 +840,7 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
ERROR2: ERROR2:
i2c_detach_client(new_client); i2c_detach_client(new_client);
ERROR1: ERROR1:
kfree(new_client); kfree(data);
ERROR0: ERROR0:
return err; return err;
} }
...@@ -852,16 +855,11 @@ static int asb100_detach_client(struct i2c_client *client) ...@@ -852,16 +855,11 @@ static int asb100_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
static u16 swap_bytes(u16 val)
{
return (val >> 8) | (val << 8);
}
/* The SMBus locks itself, usually, but nothing may access the chip between /* The SMBus locks itself, usually, but nothing may access the chip between
bank switches. */ bank switches. */
static int asb100_read_value(struct i2c_client *client, u16 reg) static int asb100_read_value(struct i2c_client *client, u16 reg)
...@@ -886,17 +884,17 @@ static int asb100_read_value(struct i2c_client *client, u16 reg) ...@@ -886,17 +884,17 @@ static int asb100_read_value(struct i2c_client *client, u16 reg)
/* convert from ISA to LM75 I2C addresses */ /* convert from ISA to LM75 I2C addresses */
switch (reg & 0xff) { switch (reg & 0xff) {
case 0x50: /* TEMP */ case 0x50: /* TEMP */
res = swap_bytes(i2c_smbus_read_word_data (cl, 0)); res = swab16(i2c_smbus_read_word_data (cl, 0));
break; break;
case 0x52: /* CONFIG */ case 0x52: /* CONFIG */
res = i2c_smbus_read_byte_data(cl, 1); res = i2c_smbus_read_byte_data(cl, 1);
break; break;
case 0x53: /* HYST */ case 0x53: /* HYST */
res = swap_bytes(i2c_smbus_read_word_data (cl, 2)); res = swab16(i2c_smbus_read_word_data (cl, 2));
break; break;
case 0x55: /* MAX */ case 0x55: /* MAX */
default: default:
res = swap_bytes(i2c_smbus_read_word_data (cl, 3)); res = swab16(i2c_smbus_read_word_data (cl, 3));
break; break;
} }
} }
...@@ -934,10 +932,10 @@ static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value) ...@@ -934,10 +932,10 @@ static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value)
i2c_smbus_write_byte_data(cl, 1, value & 0xff); i2c_smbus_write_byte_data(cl, 1, value & 0xff);
break; break;
case 0x53: /* HYST */ case 0x53: /* HYST */
i2c_smbus_write_word_data(cl, 2, swap_bytes(value)); i2c_smbus_write_word_data(cl, 2, swab16(value));
break; break;
case 0x55: /* MAX */ case 0x55: /* MAX */
i2c_smbus_write_word_data(cl, 3, swap_bytes(value)); i2c_smbus_write_word_data(cl, 3, swab16(value));
break; break;
} }
} }
......
...@@ -70,6 +70,7 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low") ...@@ -70,6 +70,7 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low")
/* Each client has this additional data */ /* Each client has this additional data */
struct ds1621_data { struct ds1621_data {
struct i2c_client client;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -97,11 +98,6 @@ static struct i2c_driver ds1621_driver = { ...@@ -97,11 +98,6 @@ static struct i2c_driver ds1621_driver = {
static int ds1621_id = 0; static int ds1621_id = 0;
static u16 swap_bytes(u16 val)
{
return (val >> 8) | (val << 8);
}
/* All registers are word-sized, except for the configuration register. /* All registers are word-sized, except for the configuration register.
DS1621 uses a high-byte first convention, which is exactly opposite to DS1621 uses a high-byte first convention, which is exactly opposite to
the usual practice. */ the usual practice. */
...@@ -110,7 +106,7 @@ static int ds1621_read_value(struct i2c_client *client, u8 reg) ...@@ -110,7 +106,7 @@ static int ds1621_read_value(struct i2c_client *client, u8 reg)
if (reg == DS1621_REG_CONF) if (reg == DS1621_REG_CONF)
return i2c_smbus_read_byte_data(client, reg); return i2c_smbus_read_byte_data(client, reg);
else else
return swap_bytes(i2c_smbus_read_word_data(client, reg)); return swab16(i2c_smbus_read_word_data(client, reg));
} }
/* All registers are word-sized, except for the configuration register. /* All registers are word-sized, except for the configuration register.
...@@ -121,8 +117,7 @@ static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value) ...@@ -121,8 +117,7 @@ static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value)
if (reg == DS1621_REG_CONF) if (reg == DS1621_REG_CONF)
return i2c_smbus_write_byte_data(client, reg, value); return i2c_smbus_write_byte_data(client, reg, value);
else else
return i2c_smbus_write_word_data(client, reg, return i2c_smbus_write_word_data(client, reg, swab16(value));
swap_bytes(value));
} }
static void ds1621_init_client(struct i2c_client *client) static void ds1621_init_client(struct i2c_client *client)
...@@ -202,16 +197,13 @@ int ds1621_detect(struct i2c_adapter *adapter, int address, ...@@ -202,16 +197,13 @@ int ds1621_detect(struct i2c_adapter *adapter, int address,
/* OK. For now, we presume we have a valid client. We now create the /* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access ds1621_{read,write}_value. */ But it allows us to access ds1621_{read,write}_value. */
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct ds1621_data), GFP_KERNEL))) {
sizeof(struct ds1621_data),
GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
memset(new_client, 0, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct ds1621_data));
sizeof(struct ds1621_data));
data = (struct ds1621_data *) (new_client + 1); new_client = &data->client;
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -264,7 +256,7 @@ int ds1621_detect(struct i2c_adapter *adapter, int address, ...@@ -264,7 +256,7 @@ int ds1621_detect(struct i2c_adapter *adapter, int address,
/* OK, this is not exactly good programming practice, usually. But it is /* OK, this is not exactly good programming practice, usually. But it is
very code-efficient in this case. */ very code-efficient in this case. */
exit_free: exit_free:
kfree(new_client); kfree(data);
exit: exit:
return err; return err;
} }
...@@ -274,12 +266,12 @@ static int ds1621_detach_client(struct i2c_client *client) ...@@ -274,12 +266,12 @@ static int ds1621_detach_client(struct i2c_client *client)
int err; int err;
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, dev_err(&client->dev, "Client deregistration failed, "
"ds1621.o: Client deregistration failed, client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
...@@ -63,6 +63,7 @@ enum eeprom_nature { ...@@ -63,6 +63,7 @@ enum eeprom_nature {
/* Each client has this additional data */ /* Each client has this additional data */
struct eeprom_data { struct eeprom_data {
struct i2c_client client;
struct semaphore update_lock; struct semaphore update_lock;
u8 valid; /* bitfield, bit!=0 if slice is valid */ u8 valid; /* bitfield, bit!=0 if slice is valid */
unsigned long last_updated[8]; /* In jiffies, 8 slices */ unsigned long last_updated[8]; /* In jiffies, 8 slices */
...@@ -187,17 +188,14 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -187,17 +188,14 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the /* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access eeprom_{read,write}_value. */ But it allows us to access eeprom_{read,write}_value. */
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
sizeof(struct eeprom_data),
GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct eeprom_data));
sizeof(struct eeprom_data));
data = (struct eeprom_data *) (new_client + 1); new_client = &data->client;
memset(data, 0xff, EEPROM_SIZE); memset(data->data, 0xff, EEPROM_SIZE);
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -244,7 +242,7 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -244,7 +242,7 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_kfree: exit_kfree:
kfree(new_client); kfree(data);
exit: exit:
return err; return err;
} }
...@@ -259,7 +257,7 @@ static int eeprom_detach_client(struct i2c_client *client) ...@@ -259,7 +257,7 @@ static int eeprom_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
...@@ -133,6 +133,7 @@ static struct i2c_driver fscher_driver = { ...@@ -133,6 +133,7 @@ static struct i2c_driver fscher_driver = {
*/ */
struct fscher_data { struct fscher_data {
struct i2c_client client;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -309,17 +310,15 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -309,17 +310,15 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the /* OK. For now, we presume we have a valid client. We now create the
* client structure, even though we cannot fill it completely yet. * client structure, even though we cannot fill it completely yet.
* But it allows us to access i2c_smbus_read_byte_data. */ * But it allows us to access i2c_smbus_read_byte_data. */
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct fscher_data), GFP_KERNEL))) {
sizeof(struct fscher_data), GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct fscher_data));
sizeof(struct fscher_data));
/* The Hermes-specific data is placed right after the common I2C /* The common I2C client data is placed right before the
* client data. */ * Hermes-specific data. */
data = (struct fscher_data *) (new_client + 1); new_client = &data->client;
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -371,7 +370,7 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -371,7 +370,7 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_free: exit_free:
kfree(new_client); kfree(data);
exit: exit:
return err; return err;
} }
...@@ -386,7 +385,7 @@ static int fscher_detach_client(struct i2c_client *client) ...@@ -386,7 +385,7 @@ static int fscher_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
...@@ -513,7 +512,7 @@ static ssize_t set_fan_div(struct i2c_client *client, struct fscher_data *data, ...@@ -513,7 +512,7 @@ static ssize_t set_fan_div(struct i2c_client *client, struct fscher_data *data,
default: default:
dev_err(&client->dev, "fan_div value %ld not " dev_err(&client->dev, "fan_div value %ld not "
"supported. Choose one of 2, 4 or 8!\n", v); "supported. Choose one of 2, 4 or 8!\n", v);
return -1; return -EINVAL;
} }
/* bits 2..7 reserved => mask with 0x03 */ /* bits 2..7 reserved => mask with 0x03 */
......
...@@ -118,6 +118,7 @@ static inline u8 FAN_TO_REG(long rpm, int div) ...@@ -118,6 +118,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
/* Each client has this additional data */ /* Each client has this additional data */
struct gl518_data { struct gl518_data {
struct i2c_client client;
enum chips type; enum chips type;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -354,16 +355,13 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -354,16 +355,13 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access gl518_{read,write}_value. */ But it allows us to access gl518_{read,write}_value. */
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct gl518_data), GFP_KERNEL))) {
sizeof(struct gl518_data),
GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct gl518_data));
sizeof(struct gl518_data));
data = (struct gl518_data *) (new_client + 1); new_client = &data->client;
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
...@@ -445,7 +443,7 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -445,7 +443,7 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
very code-efficient in this case. */ very code-efficient in this case. */
exit_free: exit_free:
kfree(new_client); kfree(data);
exit: exit:
return err; return err;
} }
...@@ -479,23 +477,18 @@ static int gl518_detach_client(struct i2c_client *client) ...@@ -479,23 +477,18 @@ static int gl518_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
static inline u16 swap_bytes(u16 val)
{
return (val >> 8) | (val << 8);
}
/* Registers 0x07 to 0x0c are word-sized, others are byte-sized /* Registers 0x07 to 0x0c are word-sized, others are byte-sized
GL518 uses a high-byte first convention, which is exactly opposite to GL518 uses a high-byte first convention, which is exactly opposite to
the usual practice. */ the usual practice. */
static int gl518_read_value(struct i2c_client *client, u8 reg) static int gl518_read_value(struct i2c_client *client, u8 reg)
{ {
if ((reg >= 0x07) && (reg <= 0x0c)) if ((reg >= 0x07) && (reg <= 0x0c))
return swap_bytes(i2c_smbus_read_word_data(client, reg)); return swab16(i2c_smbus_read_word_data(client, reg));
else else
return i2c_smbus_read_byte_data(client, reg); return i2c_smbus_read_byte_data(client, reg);
} }
...@@ -506,8 +499,7 @@ static int gl518_read_value(struct i2c_client *client, u8 reg) ...@@ -506,8 +499,7 @@ static int gl518_read_value(struct i2c_client *client, u8 reg)
static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value) static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value)
{ {
if ((reg >= 0x07) && (reg <= 0x0c)) if ((reg >= 0x07) && (reg <= 0x0c))
return i2c_smbus_write_word_data(client, reg, return i2c_smbus_write_word_data(client, reg, swab16(value));
swap_bytes(value));
else else
return i2c_smbus_write_byte_data(client, reg, value); return i2c_smbus_write_byte_data(client, reg, value);
} }
......
...@@ -134,6 +134,7 @@ static int DIV_TO_REG(int val) ...@@ -134,6 +134,7 @@ static int DIV_TO_REG(int val)
dynamically allocated, at the same time when a new it87 client is dynamically allocated, at the same time when a new it87 client is
allocated. */ allocated. */
struct it87_data { struct it87_data {
struct i2c_client client;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -366,7 +367,7 @@ static ssize_t set_sensor(struct device *dev, const char *buf, ...@@ -366,7 +367,7 @@ static ssize_t set_sensor(struct device *dev, const char *buf,
else if (val == 2) else if (val == 2)
data->sensor |= 8 << nr; data->sensor |= 8 << nr;
else if (val != 0) else if (val != 0)
return -1; return -EINVAL;
it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor); it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor);
return count; return count;
} }
...@@ -508,7 +509,7 @@ static int it87_attach_adapter(struct i2c_adapter *adapter) ...@@ -508,7 +509,7 @@ static int it87_attach_adapter(struct i2c_adapter *adapter)
int it87_detect(struct i2c_adapter *adapter, int address, int kind) int it87_detect(struct i2c_adapter *adapter, int address, int kind)
{ {
int i; int i;
struct i2c_client *new_client = NULL; struct i2c_client *new_client;
struct it87_data *data; struct it87_data *data;
int err = 0; int err = 0;
const char *name = ""; const char *name = "";
...@@ -532,12 +533,12 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -532,12 +533,12 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
/* We need the timeouts for at least some IT87-like chips. But only /* We need the timeouts for at least some IT87-like chips. But only
if we read 'undefined' registers. */ if we read 'undefined' registers. */
i = inb_p(address + 1); i = inb_p(address + 1);
if (inb_p(address + 2) != i) if (inb_p(address + 2) != i
goto ERROR1; || inb_p(address + 3) != i
if (inb_p(address + 3) != i) || inb_p(address + 7) != i) {
goto ERROR1; err = -ENODEV;
if (inb_p(address + 7) != i)
goto ERROR1; goto ERROR1;
}
#undef REALLY_SLOW_IO #undef REALLY_SLOW_IO
/* Let's just hope nothing breaks here */ /* Let's just hope nothing breaks here */
...@@ -545,7 +546,8 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -545,7 +546,8 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
outb_p(~i & 0x7f, address + 5); outb_p(~i & 0x7f, address + 5);
if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) { if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
outb_p(i, address + 5); outb_p(i, address + 5);
return 0; err = -ENODEV;
goto ERROR1;
} }
} }
} }
...@@ -554,16 +556,13 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -554,16 +556,13 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access it87_{read,write}_value. */ But it allows us to access it87_{read,write}_value. */
if (!(new_client = kmalloc((sizeof(struct i2c_client)) + if (!(data = kmalloc(sizeof(struct it87_data), GFP_KERNEL))) {
sizeof(struct it87_data),
GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto ERROR1; goto ERROR1;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct it87_data));
sizeof(struct it87_data));
data = (struct it87_data *) (new_client + 1); new_client = &data->client;
if (is_isa) if (is_isa)
init_MUTEX(&data->lock); init_MUTEX(&data->lock);
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
...@@ -575,11 +574,12 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -575,11 +574,12 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
/* Now, we do the remaining detection. */ /* Now, we do the remaining detection. */
if (kind < 0) { if (kind < 0) {
if (it87_read_value(new_client, IT87_REG_CONFIG) & 0x80) if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80)
goto ERROR1; || (!is_isa
if (!is_isa && it87_read_value(new_client, IT87_REG_I2C_ADDR) != address)) {
&& (it87_read_value(new_client, IT87_REG_I2C_ADDR) != err = -ENODEV;
address)) goto ERROR1; goto ERROR2;
}
} }
/* Determine the chip type. */ /* Determine the chip type. */
...@@ -594,7 +594,8 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -594,7 +594,8 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
"Ignoring 'force' parameter for unknown chip at " "Ignoring 'force' parameter for unknown chip at "
"adapter %d, address 0x%02x\n", "adapter %d, address 0x%02x\n",
i2c_adapter_id(adapter), address); i2c_adapter_id(adapter), address);
goto ERROR1; err = -ENODEV;
goto ERROR2;
} }
} }
...@@ -613,7 +614,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -613,7 +614,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
/* Tell the I2C layer a new client has arrived */ /* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto ERROR1; goto ERROR2;
/* Initialize the IT87 chip */ /* Initialize the IT87 chip */
it87_init_client(new_client, data); it87_init_client(new_client, data);
...@@ -669,9 +670,9 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -669,9 +670,9 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR2:
kfree(data);
ERROR1: ERROR1:
kfree(new_client);
if (is_isa) if (is_isa)
release_region(address, IT87_EXTENT); release_region(address, IT87_EXTENT);
ERROR0: ERROR0:
...@@ -690,7 +691,7 @@ static int it87_detach_client(struct i2c_client *client) ...@@ -690,7 +691,7 @@ static int it87_detach_client(struct i2c_client *client)
if(i2c_is_isa_client(client)) if(i2c_is_isa_client(client))
release_region(client->addr, IT87_EXTENT); release_region(client->addr, IT87_EXTENT);
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
...@@ -46,6 +46,7 @@ SENSORS_INSMOD_1(lm75); ...@@ -46,6 +46,7 @@ SENSORS_INSMOD_1(lm75);
/* Each client has this additional data */ /* Each client has this additional data */
struct lm75_data { struct lm75_data {
struct i2c_client client;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -135,16 +136,13 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -135,16 +136,13 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the /* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access lm75_{read,write}_value. */ But it allows us to access lm75_{read,write}_value. */
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct lm75_data), GFP_KERNEL))) {
sizeof(struct lm75_data),
GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct lm75_data));
sizeof(struct lm75_data));
data = (struct lm75_data *) (new_client + 1); new_client = &data->client;
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -194,7 +192,7 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -194,7 +192,7 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_free: exit_free:
kfree(new_client); kfree(data);
exit: exit:
return err; return err;
} }
...@@ -202,15 +200,10 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -202,15 +200,10 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
static int lm75_detach_client(struct i2c_client *client) static int lm75_detach_client(struct i2c_client *client)
{ {
i2c_detach_client(client); i2c_detach_client(client);
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
static u16 swap_bytes(u16 val)
{
return (val >> 8) | (val << 8);
}
/* All registers are word-sized, except for the configuration register. /* All registers are word-sized, except for the configuration register.
LM75 uses a high-byte first convention, which is exactly opposite to LM75 uses a high-byte first convention, which is exactly opposite to
the usual practice. */ the usual practice. */
...@@ -219,7 +212,7 @@ static int lm75_read_value(struct i2c_client *client, u8 reg) ...@@ -219,7 +212,7 @@ static int lm75_read_value(struct i2c_client *client, u8 reg)
if (reg == LM75_REG_CONF) if (reg == LM75_REG_CONF)
return i2c_smbus_read_byte_data(client, reg); return i2c_smbus_read_byte_data(client, reg);
else else
return swap_bytes(i2c_smbus_read_word_data(client, reg)); return swab16(i2c_smbus_read_word_data(client, reg));
} }
/* All registers are word-sized, except for the configuration register. /* All registers are word-sized, except for the configuration register.
...@@ -230,8 +223,7 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) ...@@ -230,8 +223,7 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
if (reg == LM75_REG_CONF) if (reg == LM75_REG_CONF)
return i2c_smbus_write_byte_data(client, reg, value); return i2c_smbus_write_byte_data(client, reg, value);
else else
return i2c_smbus_write_word_data(client, reg, return i2c_smbus_write_word_data(client, reg, swab16(value));
swap_bytes(value));
} }
static void lm75_init_client(struct i2c_client *client) static void lm75_init_client(struct i2c_client *client)
......
...@@ -192,6 +192,7 @@ static inline u8 DIV_TO_REG(int val) ...@@ -192,6 +192,7 @@ static inline u8 DIV_TO_REG(int val)
dynamically allocated, at the same time when a new lm78 client is dynamically allocated, at the same time when a new lm78 client is
allocated. */ allocated. */
struct lm78_data { struct lm78_data {
struct i2c_client client;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -552,16 +553,13 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -552,16 +553,13 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access lm78_{read,write}_value. */ But it allows us to access lm78_{read,write}_value. */
if (!(new_client = kmalloc((sizeof(struct i2c_client)) + if (!(data = kmalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
sizeof(struct lm78_data),
GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto ERROR1; goto ERROR1;
} }
memset(new_client, 0, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct lm78_data));
sizeof(struct lm78_data));
data = (struct lm78_data *) (new_client + 1); new_client = &data->client;
if (is_isa) if (is_isa)
init_MUTEX(&data->lock); init_MUTEX(&data->lock);
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
...@@ -625,6 +623,12 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -625,6 +623,12 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
/* Initialize the LM78 chip */ /* Initialize the LM78 chip */
lm78_init_client(new_client); lm78_init_client(new_client);
/* A few vars need to be filled upon startup */
for (i = 0; i < 3; i++) {
data->fan_min[i] = lm78_read_value(new_client,
LM78_REG_FAN_MIN(i));
}
/* Register sysfs hooks */ /* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_in0_input); device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in0_min); device_create_file(&new_client->dev, &dev_attr_in0_min);
...@@ -665,7 +669,7 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -665,7 +669,7 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR2: ERROR2:
kfree(new_client); kfree(data);
ERROR1: ERROR1:
if (is_isa) if (is_isa)
release_region(address, LM78_EXTENT); release_region(address, LM78_EXTENT);
...@@ -688,7 +692,7 @@ static int lm78_detach_client(struct i2c_client *client) ...@@ -688,7 +692,7 @@ static int lm78_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
...@@ -44,10 +44,9 @@ SENSORS_INSMOD_1(lm80); ...@@ -44,10 +44,9 @@ SENSORS_INSMOD_1(lm80);
#define LM80_REG_IN_MIN(nr) (0x2b + (nr) * 2) #define LM80_REG_IN_MIN(nr) (0x2b + (nr) * 2)
#define LM80_REG_IN(nr) (0x20 + (nr)) #define LM80_REG_IN(nr) (0x20 + (nr))
#define LM80_REG_FAN1_MIN 0x3c
#define LM80_REG_FAN2_MIN 0x3d
#define LM80_REG_FAN1 0x28 #define LM80_REG_FAN1 0x28
#define LM80_REG_FAN2 0x29 #define LM80_REG_FAN2 0x29
#define LM80_REG_FAN_MIN(nr) (0x3b + (nr))
#define LM80_REG_TEMP 0x27 #define LM80_REG_TEMP 0x27
#define LM80_REG_TEMP_HOT_MAX 0x38 #define LM80_REG_TEMP_HOT_MAX 0x38
...@@ -69,7 +68,7 @@ SENSORS_INSMOD_1(lm80); ...@@ -69,7 +68,7 @@ SENSORS_INSMOD_1(lm80);
these macros are called: arguments may be evaluated more than once. these macros are called: arguments may be evaluated more than once.
Fixing this is just not worth it. */ Fixing this is just not worth it. */
#define IN_TO_REG(val) (SENSORS_LIMIT((val)/10,0,255)) #define IN_TO_REG(val) (SENSORS_LIMIT(((val)+5)/10,0,255))
#define IN_FROM_REG(val) ((val)*10) #define IN_FROM_REG(val) ((val)*10)
static inline unsigned char FAN_TO_REG(unsigned rpm, unsigned div) static inline unsigned char FAN_TO_REG(unsigned rpm, unsigned div)
...@@ -111,6 +110,7 @@ static inline long TEMP_FROM_REG(u16 temp) ...@@ -111,6 +110,7 @@ static inline long TEMP_FROM_REG(u16 temp)
*/ */
struct lm80_data { struct lm80_data {
struct i2c_client client;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -250,8 +250,46 @@ static ssize_t set_fan_##suffix(struct device *dev, const char *buf, \ ...@@ -250,8 +250,46 @@ static ssize_t set_fan_##suffix(struct device *dev, const char *buf, \
lm80_write_value(client, reg, data->value); \ lm80_write_value(client, reg, data->value); \
return count; \ return count; \
} }
set_fan(min1, fan_min[0], LM80_REG_FAN1_MIN, fan_div[0]); set_fan(min1, fan_min[0], LM80_REG_FAN_MIN(1), fan_div[0]);
set_fan(min2, fan_min[1], LM80_REG_FAN2_MIN, fan_div[1]); set_fan(min2, fan_min[1], LM80_REG_FAN_MIN(2), fan_div[1]);
/* Note: we save and restore the fan minimum here, because its value is
determined in part by the fan divisor. This follows the principle of
least suprise; the user doesn't expect the fan minimum to change just
because the divisor changed. */
static ssize_t set_fan_div(struct device *dev, const char *buf,
size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm80_data *data = i2c_get_clientdata(client);
unsigned long min;
u8 reg;
/* Save fan_min */
min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr]));
data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10));
reg = (lm80_read_value(client, LM80_REG_FANDIV) & ~(3 << (2 * (nr + 1))))
| (data->fan_div[nr] << (2 * (nr + 1)));
lm80_write_value(client, LM80_REG_FANDIV, reg);
/* Restore fan_min */
data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]);
return count;
}
#define set_fan_div(number) \
static ssize_t set_fan_div##number(struct device *dev, const char *buf, \
size_t count) \
{ \
return set_fan_div(dev, buf, count, number - 1); \
}
set_fan_div(1);
set_fan_div(2);
static ssize_t show_temp_input1(struct device *dev, char *buf) static ssize_t show_temp_input1(struct device *dev, char *buf)
{ {
...@@ -319,8 +357,8 @@ static DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min2, ...@@ -319,8 +357,8 @@ static DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min2,
set_fan_min2); set_fan_min2);
static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input1, NULL); static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input1, NULL);
static DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input2, NULL); static DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input2, NULL);
static DEVICE_ATTR(fan1_div, S_IRUGO, show_fan_div1, NULL); static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, show_fan_div1, set_fan_div1);
static DEVICE_ATTR(fan2_div, S_IRUGO, show_fan_div2, NULL); static DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO, show_fan_div2, set_fan_div2);
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_hot_max, static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_hot_max,
set_temp_hot_max); set_temp_hot_max);
...@@ -357,15 +395,13 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -357,15 +395,13 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK. For now, we presume we have a valid client. We now create the /* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access lm80_{read,write}_value. */ But it allows us to access lm80_{read,write}_value. */
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct lm80_data), GFP_KERNEL))) {
sizeof(struct lm80_data), GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct lm80_data));
sizeof(struct lm80_data));
data = (struct lm80_data *) (new_client + 1); new_client = &data->client;
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -401,6 +437,10 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -401,6 +437,10 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
/* Initialize the LM80 chip */ /* Initialize the LM80 chip */
lm80_init_client(new_client); lm80_init_client(new_client);
/* A few vars need to be filled upon startup */
data->fan_min[0] = lm80_read_value(new_client, LM80_REG_FAN_MIN(1));
data->fan_min[1] = lm80_read_value(new_client, LM80_REG_FAN_MIN(2));
/* Register sysfs hooks */ /* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_in0_min); device_create_file(&new_client->dev, &dev_attr_in0_min);
device_create_file(&new_client->dev, &dev_attr_in1_min); device_create_file(&new_client->dev, &dev_attr_in1_min);
...@@ -439,7 +479,7 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -439,7 +479,7 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
error_free: error_free:
kfree(new_client); kfree(data);
exit: exit:
return err; return err;
} }
...@@ -454,7 +494,7 @@ static int lm80_detach_client(struct i2c_client *client) ...@@ -454,7 +494,7 @@ static int lm80_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
...@@ -504,10 +544,10 @@ static struct lm80_data *lm80_update_device(struct device *dev) ...@@ -504,10 +544,10 @@ static struct lm80_data *lm80_update_device(struct device *dev)
} }
data->fan[0] = lm80_read_value(client, LM80_REG_FAN1); data->fan[0] = lm80_read_value(client, LM80_REG_FAN1);
data->fan_min[0] = data->fan_min[0] =
lm80_read_value(client, LM80_REG_FAN1_MIN); lm80_read_value(client, LM80_REG_FAN_MIN(1));
data->fan[1] = lm80_read_value(client, LM80_REG_FAN2); data->fan[1] = lm80_read_value(client, LM80_REG_FAN2);
data->fan_min[1] = data->fan_min[1] =
lm80_read_value(client, LM80_REG_FAN2_MIN); lm80_read_value(client, LM80_REG_FAN_MIN(2));
data->temp = data->temp =
(lm80_read_value(client, LM80_REG_TEMP) << 8) | (lm80_read_value(client, LM80_REG_TEMP) << 8) |
......
...@@ -134,6 +134,7 @@ static struct i2c_driver lm83_driver = { ...@@ -134,6 +134,7 @@ static struct i2c_driver lm83_driver = {
*/ */
struct lm83_data { struct lm83_data {
struct i2c_client client;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -234,17 +235,15 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -234,17 +235,15 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit; goto exit;
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct lm83_data), GFP_KERNEL))) {
sizeof(struct lm83_data), GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct lm83_data));
sizeof(struct lm83_data));
/* The LM83-specific data is placed right after the common I2C /* The common I2C client data is placed right after the
* client data. */ * LM83-specific data. */
data = (struct lm83_data *) (new_client + 1); new_client = &data->client;
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -329,7 +328,7 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -329,7 +328,7 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_free: exit_free:
kfree(new_client); kfree(data);
exit: exit:
return err; return err;
} }
...@@ -344,7 +343,7 @@ static int lm83_detach_client(struct i2c_client *client) ...@@ -344,7 +343,7 @@ static int lm83_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
...@@ -351,6 +351,7 @@ struct lm85_autofan { ...@@ -351,6 +351,7 @@ struct lm85_autofan {
}; };
struct lm85_data { struct lm85_data {
struct i2c_client client;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -736,16 +737,13 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -736,16 +737,13 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access lm85_{read,write}_value. */ But it allows us to access lm85_{read,write}_value. */
if (!(new_client = kmalloc((sizeof(struct i2c_client)) + if (!(data = kmalloc(sizeof(struct lm85_data), GFP_KERNEL))) {
sizeof(struct lm85_data),
GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto ERROR0; goto ERROR0;
} }
memset(data, 0, sizeof(struct lm85_data));
memset(new_client, 0, sizeof(struct i2c_client) + new_client = &data->client;
sizeof(struct lm85_data));
data = (struct lm85_data *) (new_client + 1);
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -886,7 +884,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -886,7 +884,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
/* Error out and cleanup code */ /* Error out and cleanup code */
ERROR1: ERROR1:
kfree(new_client); kfree(data);
ERROR0: ERROR0:
return err; return err;
} }
...@@ -894,7 +892,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -894,7 +892,7 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
int lm85_detach_client(struct i2c_client *client) int lm85_detach_client(struct i2c_client *client)
{ {
i2c_detach_client(client); i2c_detach_client(client);
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
...@@ -142,6 +142,7 @@ static struct i2c_driver lm90_driver = { ...@@ -142,6 +142,7 @@ static struct i2c_driver lm90_driver = {
*/ */
struct lm90_data { struct lm90_data {
struct i2c_client client;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -280,17 +281,15 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -280,17 +281,15 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit; goto exit;
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct lm90_data), GFP_KERNEL))) {
sizeof(struct lm90_data), GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct lm90_data));
sizeof(struct lm90_data));
/* The LM90-specific data is placed right after the common I2C /* The common I2C client data is placed right before the
* client data. */ LM90-specific data. */
data = (struct lm90_data *) (new_client + 1); new_client = &data->client;
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -390,7 +389,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -390,7 +389,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_free: exit_free:
kfree(new_client); kfree(data);
exit: exit:
return err; return err;
} }
...@@ -420,7 +419,7 @@ static int lm90_detach_client(struct i2c_client *client) ...@@ -420,7 +419,7 @@ static int lm90_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
/*
pcf8574.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring
Copyright (c) 2000 Frodo Looijaard <frodol@dds.nl>,
Philip Edelbrock <phil@netroedge.com>,
Dan Eaton <dan.eaton@rocketlogix.com>
Ported to Linux 2.6 by Aurelien Jarno <aurel32@debian.org> with
the help of Jean Delvare <khali@linux-fr.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* A few notes about the PCF8574:
* The PCF8574 is an 8-bit I/O expander for the I2C bus produced by
Philips Semiconductors. It is designed to provide a byte I2C
interface to up to 8 separate devices.
* The PCF8574 appears as a very simple SMBus device which can be
read from or written to with SMBUS byte read/write accesses.
--Dan
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/i2c-sensor.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { I2C_CLIENT_END };
static unsigned short normal_i2c_range[] = { 0x20, 0x27, 0x38, 0x3f, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */
SENSORS_INSMOD_2(pcf8574, pcf8574a);
/* Initial values */
#define PCF8574_INIT 255 /* All outputs on (input mode) */
/* Each client has this additional data */
struct pcf8574_data {
struct i2c_client client;
struct semaphore update_lock;
u8 read, write; /* Register values */
};
static int pcf8574_attach_adapter(struct i2c_adapter *adapter);
static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind);
static int pcf8574_detach_client(struct i2c_client *client);
static void pcf8574_init_client(struct i2c_client *client);
static struct pcf8574_data *pcf8574_update_client(struct device *dev);
/* This is the driver that will be inserted */
static struct i2c_driver pcf8574_driver = {
.owner = THIS_MODULE,
.name = "pcf8574",
.id = I2C_DRIVERID_PCF8574,
.flags = I2C_DF_NOTIFY,
.attach_adapter = pcf8574_attach_adapter,
.detach_client = pcf8574_detach_client,
};
static int pcf8574_id = 0;
/* following are the sysfs callback functions */
static ssize_t show_read(struct device *dev, char *buf)
{
struct pcf8574_data *data = pcf8574_update_client(dev);
return sprintf(buf, "%u\n", data->read);
}
static DEVICE_ATTR(read, S_IRUGO, show_read, NULL);
static ssize_t show_write(struct device *dev, char *buf)
{
struct pcf8574_data *data = i2c_get_clientdata(to_i2c_client(dev));
return sprintf(buf, "%u\n", data->write);
}
static ssize_t set_write(struct device *dev, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf8574_data *data = i2c_get_clientdata(client);
data->write = simple_strtoul(buf, NULL, 10);
i2c_smbus_write_byte(client, data->write);
return count;
}
static DEVICE_ATTR(write, S_IWUSR | S_IRUGO, show_write, set_write);
/*
* Real code
*/
static int pcf8574_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_detect(adapter, &addr_data, pcf8574_detect);
}
/* This function is called by i2c_detect */
int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct pcf8574_data *data;
int err = 0;
const char *client_name = "";
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. */
if (!(data = kmalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
memset(data, 0, sizeof(struct pcf8574_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &pcf8574_driver;
new_client->flags = 0;
/* Now, we would do the remaining detection. But the PCF8574 is plainly
impossible to detect! Stupid chip. */
/* Determine the chip type */
if (kind <= 0) {
if (address >= 0x38 && address <= 0x3f)
kind = pcf8574a;
else
kind = pcf8574;
}
if (kind == pcf8574a)
client_name = "pcf8574a";
else
client_name = "pcf8574";
/* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
new_client->id = pcf8574_id++;
init_MUTEX(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/* Initialize the PCF8574 chip */
pcf8574_init_client(new_client);
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_read);
device_create_file(&new_client->dev, &dev_attr_write);
return 0;
/* OK, this is not exactly good programming practice, usually. But it is
very code-efficient in this case. */
exit_free:
kfree(data);
exit:
return err;
}
static int pcf8574_detach_client(struct i2c_client *client)
{
int err;
if ((err = i2c_detach_client(client))) {
dev_err(&client->dev,
"Client deregistration failed, client not detached.\n");
return err;
}
kfree(i2c_get_clientdata(client));
return 0;
}
/* Called when we have found a new PCF8574. */
static void pcf8574_init_client(struct i2c_client *client)
{
struct pcf8574_data *data = i2c_get_clientdata(client);
data->write = PCF8574_INIT;
i2c_smbus_write_byte(client, data->write);
}
static struct pcf8574_data *pcf8574_update_client(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf8574_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
dev_dbg(&client->dev, "Starting pcf8574 update\n");
data->read = i2c_smbus_read_byte(client);
up(&data->update_lock);
return data;
}
static int __init pcf8574_init(void)
{
return i2c_add_driver(&pcf8574_driver);
}
static void __exit pcf8574_exit(void)
{
i2c_del_driver(&pcf8574_driver);
}
MODULE_AUTHOR
("Frodo Looijaard <frodol@dds.nl>, "
"Philip Edelbrock <phil@netroedge.com>, "
"Dan Eaton <dan.eaton@rocketlogix.com> "
"and Aurelien Jarno <aurelien@aurel32.net>");
MODULE_DESCRIPTION("PCF8574 driver");
MODULE_LICENSE("GPL");
module_init(pcf8574_init);
module_exit(pcf8574_exit);
/*
pcf8591.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring
Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net>
Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
the help of Jean Delvare <khali@linux-fr.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/i2c-sensor.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { I2C_CLIENT_END };
static unsigned short normal_i2c_range[] = { 0x48, 0x4f, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */
SENSORS_INSMOD_1(pcf8591);
static int input_mode;
MODULE_PARM(input_mode, "i");
MODULE_PARM_DESC(input_mode,
"Analog input mode:\n"
" 0 = four single ended inputs\n"
" 1 = three differential inputs\n"
" 2 = single ended and differential mixed\n"
" 3 = two differential inputs\n");
/* The PCF8591 control byte
7 6 5 4 3 2 1 0
| 0 |AOEF| AIP | 0 |AINC| AICH | */
/* Analog Output Enable Flag (analog output active if 1) */
#define PCF8591_CONTROL_AOEF 0x40
/* Analog Input Programming
0x00 = four single ended inputs
0x10 = three differential inputs
0x20 = single ended and differential mixed
0x30 = two differential inputs */
#define PCF8591_CONTROL_AIP_MASK 0x30
/* Autoincrement Flag (switch on if 1) */
#define PCF8591_CONTROL_AINC 0x04
/* Channel selection
0x00 = channel 0
0x01 = channel 1
0x02 = channel 2
0x03 = channel 3 */
#define PCF8591_CONTROL_AICH_MASK 0x03
/* Initial values */
#define PCF8591_INIT_CONTROL ((input_mode << 4) | PCF8591_CONTROL_AOEF)
#define PCF8591_INIT_AOUT 0 /* DAC out = 0 */
/* Conversions */
#define REG_TO_SIGNED(reg) (((reg) & 0x80)?((reg) - 256):(reg))
struct pcf8591_data {
struct i2c_client client;
struct semaphore update_lock;
u8 control;
u8 aout;
};
static int pcf8591_attach_adapter(struct i2c_adapter *adapter);
static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind);
static int pcf8591_detach_client(struct i2c_client *client);
static void pcf8591_init_client(struct i2c_client *client);
static int pcf8591_read_channel(struct device *dev, int channel);
/* This is the driver that will be inserted */
static struct i2c_driver pcf8591_driver = {
.owner = THIS_MODULE,
.name = "pcf8591",
.id = I2C_DRIVERID_PCF8591,
.flags = I2C_DF_NOTIFY,
.attach_adapter = pcf8591_attach_adapter,
.detach_client = pcf8591_detach_client,
};
static int pcf8591_id = 0;
/* following are the sysfs callback functions */
#define show_in_channel(channel) \
static ssize_t show_in##channel##_input(struct device *dev, char *buf) \
{ \
return sprintf(buf, "%d\n", pcf8591_read_channel(dev, channel));\
} \
static DEVICE_ATTR(in##channel##_input, S_IRUGO, \
show_in##channel##_input, NULL);
show_in_channel(0);
show_in_channel(1);
show_in_channel(2);
show_in_channel(3);
static ssize_t show_out0_ouput(struct device *dev, char *buf)
{
struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
return sprintf(buf, "%d\n", data->aout * 10);
}
static ssize_t set_out0_output(struct device *dev, const char *buf, size_t count)
{
unsigned int value;
struct i2c_client *client = to_i2c_client(dev);
struct pcf8591_data *data = i2c_get_clientdata(client);
if ((value = (simple_strtoul(buf, NULL, 10) + 5) / 10) <= 255) {
data->aout = value;
i2c_smbus_write_byte_data(client, data->control, data->aout);
return count;
}
return -EINVAL;
}
static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,
show_out0_ouput, set_out0_output);
static ssize_t show_out0_enable(struct device *dev, char *buf)
{
struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
return sprintf(buf, "%u\n", !(!(data->control & PCF8591_CONTROL_AOEF)));
}
static ssize_t set_out0_enable(struct device *dev, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf8591_data *data = i2c_get_clientdata(client);
if (simple_strtoul(buf, NULL, 10))
data->control |= PCF8591_CONTROL_AOEF;
else
data->control &= ~PCF8591_CONTROL_AOEF;
i2c_smbus_write_byte(client, data->control);
return count;
}
static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO,
show_out0_enable, set_out0_enable);
/*
* Real code
*/
static int pcf8591_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_detect(adapter, &addr_data, pcf8591_detect);
}
/* This function is called by i2c_detect */
int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct pcf8591_data *data;
int err = 0;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE
| I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. */
if (!(data = kmalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
memset(data, 0, sizeof(struct pcf8591_data));
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &pcf8591_driver;
new_client->flags = 0;
/* Now, we would do the remaining detection. But the PCF8591 is plainly
impossible to detect! Stupid chip. */
/* Determine the chip type - only one kind supported! */
if (kind <= 0)
kind = pcf8591;
/* Fill in the remaining client fields and put it into the global
list */
strlcpy(new_client->name, "pcf8591", I2C_NAME_SIZE);
new_client->id = pcf8591_id++;
init_MUTEX(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_kfree;
/* Initialize the PCF8591 chip */
pcf8591_init_client(new_client);
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_out0_enable);
device_create_file(&new_client->dev, &dev_attr_out0_output);
device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in1_input);
/* Register input2 if not in "two differential inputs" mode */
if (input_mode != 3 )
device_create_file(&new_client->dev, &dev_attr_in2_input);
/* Register input3 only in "four single ended inputs" mode */
if (input_mode == 0)
device_create_file(&new_client->dev, &dev_attr_in3_input);
return 0;
/* OK, this is not exactly good programming practice, usually. But it is
very code-efficient in this case. */
exit_kfree:
kfree(data);
exit:
return err;
}
static int pcf8591_detach_client(struct i2c_client *client)
{
int err;
if ((err = i2c_detach_client(client))) {
dev_err(&client->dev,
"Client deregistration failed, client not detached.\n");
return err;
}
kfree(i2c_get_clientdata(client));
return 0;
}
/* Called when we have found a new PCF8591. */
static void pcf8591_init_client(struct i2c_client *client)
{
struct pcf8591_data *data = i2c_get_clientdata(client);
data->control = PCF8591_INIT_CONTROL;
data->aout = PCF8591_INIT_AOUT;
i2c_smbus_write_byte_data(client, data->control, data->aout);
/* The first byte transmitted contains the conversion code of the
previous read cycle. FLUSH IT! */
i2c_smbus_read_byte(client);
}
static int pcf8591_read_channel(struct device *dev, int channel)
{
u8 value;
struct i2c_client *client = to_i2c_client(dev);
struct pcf8591_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
if ((data->control & PCF8591_CONTROL_AICH_MASK) != channel) {
data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK)
| channel;
i2c_smbus_write_byte(client, data->control);
/* The first byte transmitted contains the conversion code of
the previous read cycle. FLUSH IT! */
i2c_smbus_read_byte(client);
}
value = i2c_smbus_read_byte(client);
up(&data->update_lock);
if ((channel == 2 && input_mode == 2) ||
(channel != 3 && (input_mode == 1 || input_mode == 3)))
return (10 * REG_TO_SIGNED(value));
else
return (10 * value);
}
static int __init pcf8591_init(void)
{
if (input_mode < 0 || input_mode > 3) {
printk(KERN_WARNING "pcf8591: invalid input_mode (%d)\n",
input_mode);
input_mode = 0;
}
return i2c_add_driver(&pcf8591_driver);
}
static void __exit pcf8591_exit(void)
{
i2c_del_driver(&pcf8591_driver);
}
MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
MODULE_DESCRIPTION("PCF8591 driver");
MODULE_LICENSE("GPL");
module_init(pcf8591_init);
module_exit(pcf8591_exit);
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
/* /*
Supports the Via VT82C686A, VT82C686B south bridges. Supports the Via VT82C686A, VT82C686B south bridges.
Reports all as a 686A. Reports all as a 686A.
See doc/chips/via686a for details.
Warning - only supports a single device. Warning - only supports a single device.
*/ */
...@@ -330,48 +329,11 @@ static inline long TEMP_FROM_REG10(u16 val) ...@@ -330,48 +329,11 @@ static inline long TEMP_FROM_REG10(u16 val)
#define DIV_FROM_REG(val) (1 << (val)) #define DIV_FROM_REG(val) (1 << (val))
#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) #define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
/* Initial limits */ /* For the VIA686A, we need to keep some data in memory.
#define VIA686A_INIT_IN_0 200 The structure is dynamically allocated, at the same time when a new
#define VIA686A_INIT_IN_1 250 via686a client is allocated. */
#define VIA686A_INIT_IN_2 330
#define VIA686A_INIT_IN_3 500
#define VIA686A_INIT_IN_4 1200
#define VIA686A_INIT_IN_PERCENTAGE 10
#define VIA686A_INIT_IN_MIN_0 (VIA686A_INIT_IN_0 - VIA686A_INIT_IN_0 \
* VIA686A_INIT_IN_PERCENTAGE / 100)
#define VIA686A_INIT_IN_MAX_0 (VIA686A_INIT_IN_0 + VIA686A_INIT_IN_0 \
* VIA686A_INIT_IN_PERCENTAGE / 100)
#define VIA686A_INIT_IN_MIN_1 (VIA686A_INIT_IN_1 - VIA686A_INIT_IN_1 \
* VIA686A_INIT_IN_PERCENTAGE / 100)
#define VIA686A_INIT_IN_MAX_1 (VIA686A_INIT_IN_1 + VIA686A_INIT_IN_1 \
* VIA686A_INIT_IN_PERCENTAGE / 100)
#define VIA686A_INIT_IN_MIN_2 (VIA686A_INIT_IN_2 - VIA686A_INIT_IN_2 \
* VIA686A_INIT_IN_PERCENTAGE / 100)
#define VIA686A_INIT_IN_MAX_2 (VIA686A_INIT_IN_2 + VIA686A_INIT_IN_2 \
* VIA686A_INIT_IN_PERCENTAGE / 100)
#define VIA686A_INIT_IN_MIN_3 (VIA686A_INIT_IN_3 - VIA686A_INIT_IN_3 \
* VIA686A_INIT_IN_PERCENTAGE / 100)
#define VIA686A_INIT_IN_MAX_3 (VIA686A_INIT_IN_3 + VIA686A_INIT_IN_3 \
* VIA686A_INIT_IN_PERCENTAGE / 100)
#define VIA686A_INIT_IN_MIN_4 (VIA686A_INIT_IN_4 - VIA686A_INIT_IN_4 \
* VIA686A_INIT_IN_PERCENTAGE / 100)
#define VIA686A_INIT_IN_MAX_4 (VIA686A_INIT_IN_4 + VIA686A_INIT_IN_4 \
* VIA686A_INIT_IN_PERCENTAGE / 100)
#define VIA686A_INIT_FAN_MIN 3000
#define VIA686A_INIT_TEMP_OVER 600
#define VIA686A_INIT_TEMP_HYST 500
/* For the VIA686A, we need to keep some data in memory. That
data is pointed to by via686a_list[NR]->data. The structure itself is
dynamically allocated, at the same time when a new via686a client is
allocated. */
struct via686a_data { struct via686a_data {
int sysctl_id; struct i2c_client client;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -688,16 +650,13 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -688,16 +650,13 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
return -ENODEV; return -ENODEV;
} }
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
sizeof(struct via686a_data),
GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto ERROR0; goto ERROR0;
} }
memset(data, 0, sizeof(struct via686a_data));
memset(new_client,0x00, sizeof(struct i2c_client) + new_client = &data->client;
sizeof(struct via686a_data));
data = (struct via686a_data *) (new_client + 1);
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -753,9 +712,9 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -753,9 +712,9 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR3: ERROR3:
release_region(address, VIA686A_EXTENT); kfree(data);
kfree(new_client);
ERROR0: ERROR0:
release_region(address, VIA686A_EXTENT);
return err; return err;
} }
...@@ -770,7 +729,7 @@ static int via686a_detach_client(struct i2c_client *client) ...@@ -770,7 +729,7 @@ static int via686a_detach_client(struct i2c_client *client)
} }
release_region(client->addr, VIA686A_EXTENT); release_region(client->addr, VIA686A_EXTENT);
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
...@@ -778,53 +737,13 @@ static int via686a_detach_client(struct i2c_client *client) ...@@ -778,53 +737,13 @@ static int via686a_detach_client(struct i2c_client *client)
/* Called when we have found a new VIA686A. Set limits, etc. */ /* Called when we have found a new VIA686A. Set limits, etc. */
static void via686a_init_client(struct i2c_client *client) static void via686a_init_client(struct i2c_client *client)
{ {
int i; u8 reg;
/* Reset the device */
via686a_write_value(client, VIA686A_REG_CONFIG, 0x80);
/* Have to wait for reset to complete or else the following
initializations won't work reliably. The delay was arrived at
empirically, the datasheet doesn't tell you.
Waiting for the reset bit to clear doesn't work, it
clears in about 2-4 udelays and that isn't nearly enough. */
udelay(50);
via686a_write_value(client, VIA686A_REG_IN_MIN(0),
IN_TO_REG(VIA686A_INIT_IN_MIN_0, 0));
via686a_write_value(client, VIA686A_REG_IN_MAX(0),
IN_TO_REG(VIA686A_INIT_IN_MAX_0, 0));
via686a_write_value(client, VIA686A_REG_IN_MIN(1),
IN_TO_REG(VIA686A_INIT_IN_MIN_1, 1));
via686a_write_value(client, VIA686A_REG_IN_MAX(1),
IN_TO_REG(VIA686A_INIT_IN_MAX_1, 1));
via686a_write_value(client, VIA686A_REG_IN_MIN(2),
IN_TO_REG(VIA686A_INIT_IN_MIN_2, 2));
via686a_write_value(client, VIA686A_REG_IN_MAX(2),
IN_TO_REG(VIA686A_INIT_IN_MAX_2, 2));
via686a_write_value(client, VIA686A_REG_IN_MIN(3),
IN_TO_REG(VIA686A_INIT_IN_MIN_3, 3));
via686a_write_value(client, VIA686A_REG_IN_MAX(3),
IN_TO_REG(VIA686A_INIT_IN_MAX_3, 3));
via686a_write_value(client, VIA686A_REG_IN_MIN(4),
IN_TO_REG(VIA686A_INIT_IN_MIN_4, 4));
via686a_write_value(client, VIA686A_REG_IN_MAX(4),
IN_TO_REG(VIA686A_INIT_IN_MAX_4, 4));
via686a_write_value(client, VIA686A_REG_FAN_MIN(1),
FAN_TO_REG(VIA686A_INIT_FAN_MIN, 2));
via686a_write_value(client, VIA686A_REG_FAN_MIN(2),
FAN_TO_REG(VIA686A_INIT_FAN_MIN, 2));
for (i = 0; i <= 2; i++) {
via686a_write_value(client, VIA686A_REG_TEMP_OVER(i),
TEMP_TO_REG(VIA686A_INIT_TEMP_OVER));
via686a_write_value(client, VIA686A_REG_TEMP_HYST(i),
TEMP_TO_REG(VIA686A_INIT_TEMP_HYST));
}
/* Start monitoring */ /* Start monitoring */
via686a_write_value(client, VIA686A_REG_CONFIG, 0x01); reg = via686a_read_value(client, VIA686A_REG_CONFIG);
via686a_write_value(client, VIA686A_REG_CONFIG, (reg|0x01)&0x7F);
/* Cofigure temp interrupt mode for continuous-interrupt operation */ /* Configure temp interrupt mode for continuous-interrupt operation */
via686a_write_value(client, VIA686A_REG_TEMP_MODE, via686a_write_value(client, VIA686A_REG_TEMP_MODE,
via686a_read_value(client, VIA686A_REG_TEMP_MODE) & via686a_read_value(client, VIA686A_REG_TEMP_MODE) &
!(VIA686A_TEMP_MODE_MASK | VIA686A_TEMP_MODE_CONTINUOUS)); !(VIA686A_TEMP_MODE_MASK | VIA686A_TEMP_MODE_CONTINUOUS));
......
...@@ -277,6 +277,7 @@ static inline u8 DIV_TO_REG(long val) ...@@ -277,6 +277,7 @@ static inline u8 DIV_TO_REG(long val)
data is pointed to by w83627hf_list[NR]->data. The structure itself is data is pointed to by w83627hf_list[NR]->data. The structure itself is
dynamically allocated, at the same time when a new client is allocated. */ dynamically allocated, at the same time when a new client is allocated. */
struct w83627hf_data { struct w83627hf_data {
struct i2c_client client;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -659,34 +660,37 @@ show_fan_div_reg(struct device *dev, char *buf, int nr) ...@@ -659,34 +660,37 @@ show_fan_div_reg(struct device *dev, char *buf, int nr)
(long) DIV_FROM_REG(data->fan_div[nr - 1])); (long) DIV_FROM_REG(data->fan_div[nr - 1]));
} }
/* Note: we save and restore the fan minimum here, because its value is
determined in part by the fan divisor. This follows the principle of
least suprise; the user doesn't expect the fan minimum to change just
because the divisor changed. */
static ssize_t static ssize_t
store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct w83627hf_data *data = i2c_get_clientdata(client); struct w83627hf_data *data = i2c_get_clientdata(client);
u32 val, old, old2, old3 = 0; unsigned long min;
u8 reg;
val = simple_strtoul(buf, NULL, 10); /* Save fan_min */
old = w83627hf_read_value(client, W83781D_REG_VID_FANDIV); min = FAN_FROM_REG(data->fan_min[nr],
old3 = w83627hf_read_value(client, W83781D_REG_VBAT); DIV_FROM_REG(data->fan_div[nr]));
data->fan_div[nr - 1] = DIV_TO_REG(val);
data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10));
if (nr >= 3 && data->type != w83697hf) {
old2 = w83627hf_read_value(client, W83781D_REG_PIN); reg = (w83627hf_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
old2 = (old2 & 0x3f) | ((data->fan_div[2] & 0x03) << 6); & (nr==0 ? 0xcf : 0x3f))
w83627hf_write_value(client, W83781D_REG_PIN, old2); | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));
old3 = (old3 & 0x7f) | ((data->fan_div[2] & 0x04) << 5); w83627hf_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
}
if (nr >= 2) { reg = (w83627hf_read_value(client, W83781D_REG_VBAT)
old = (old & 0x3f) | ((data->fan_div[1] & 0x03) << 6); & ~(1 << (5 + nr)))
old3 = (old3 & 0xbf) | ((data->fan_div[1] & 0x04) << 4); | ((data->fan_div[nr] & 0x04) << (3 + nr));
} w83627hf_write_value(client, W83781D_REG_VBAT, reg);
if (nr >= 1) {
old = (old & 0xcf) | ((data->fan_div[0] & 0x03) << 4); /* Restore fan_min */
w83627hf_write_value(client, W83781D_REG_VID_FANDIV, old); data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
old3 = (old3 & 0xdf) | ((data->fan_div[0] & 0x04) << 3); w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
w83627hf_write_value(client, W83781D_REG_VBAT, old3);
}
return count; return count;
} }
...@@ -700,7 +704,7 @@ static ssize_t \ ...@@ -700,7 +704,7 @@ static ssize_t \
store_regs_fan_div_##offset (struct device *dev, \ store_regs_fan_div_##offset (struct device *dev, \
const char *buf, size_t count) \ const char *buf, size_t count) \
{ \ { \
return store_fan_div_reg(dev, buf, count, offset); \ return store_fan_div_reg(dev, buf, count, offset - 1); \
} \ } \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
show_regs_fan_div_##offset, store_regs_fan_div_##offset) show_regs_fan_div_##offset, store_regs_fan_div_##offset)
...@@ -938,17 +942,13 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address, ...@@ -938,17 +942,13 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address,
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access w83627hf_{read,write}_value. */ But it allows us to access w83627hf_{read,write}_value. */
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) {
sizeof(struct w83627hf_data),
GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto ERROR1; goto ERROR1;
} }
memset(data, 0, sizeof(struct w83627hf_data));
memset(new_client, 0x00, sizeof (struct i2c_client) + new_client = &data->client;
sizeof (struct w83627hf_data));
data = (struct w83627hf_data *) (new_client + 1);
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
init_MUTEX(&data->lock); init_MUTEX(&data->lock);
...@@ -982,6 +982,11 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address, ...@@ -982,6 +982,11 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address,
/* Initialize the chip */ /* Initialize the chip */
w83627hf_init_client(new_client); w83627hf_init_client(new_client);
/* A few vars need to be filled upon startup */
data->fan_min[0] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(1));
data->fan_min[1] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(2));
data->fan_min[2] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(3));
/* Register sysfs hooks */ /* Register sysfs hooks */
device_create_file_in(new_client, 0); device_create_file_in(new_client, 0);
if (kind != w83697hf) if (kind != w83697hf)
...@@ -1034,7 +1039,7 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address, ...@@ -1034,7 +1039,7 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address,
return 0; return 0;
ERROR2: ERROR2:
kfree(new_client); kfree(data);
ERROR1: ERROR1:
release_region(address, WINB_EXTENT); release_region(address, WINB_EXTENT);
ERROR0: ERROR0:
...@@ -1052,7 +1057,7 @@ static int w83627hf_detach_client(struct i2c_client *client) ...@@ -1052,7 +1057,7 @@ static int w83627hf_detach_client(struct i2c_client *client)
} }
release_region(client->addr, WINB_EXTENT); release_region(client->addr, WINB_EXTENT);
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
Supports following chips: Supports following chips:
Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
as99127f 7 3 1? 3 0x31 0x12c3 yes no as99127f 7 3 0 3 0x31 0x12c3 yes no
as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no
w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes
w83627hf 9 3 2 3 0x21 0x5ca3 yes yes(LPC) w83627hf 9 3 2 3 0x21 0x5ca3 yes yes(LPC)
...@@ -226,6 +226,7 @@ DIV_TO_REG(long val, enum chips type) ...@@ -226,6 +226,7 @@ DIV_TO_REG(long val, enum chips type)
dynamically allocated, at the same time when a new w83781d client is dynamically allocated, at the same time when a new w83781d client is
allocated. */ allocated. */
struct w83781d_data { struct w83781d_data {
struct i2c_client client;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -275,11 +276,6 @@ static int w83781d_write_value(struct i2c_client *client, u16 register, ...@@ -275,11 +276,6 @@ static int w83781d_write_value(struct i2c_client *client, u16 register,
static struct w83781d_data *w83781d_update_device(struct device *dev); static struct w83781d_data *w83781d_update_device(struct device *dev);
static void w83781d_init_client(struct i2c_client *client); static void w83781d_init_client(struct i2c_client *client);
static inline u16 swap_bytes(u16 val)
{
return (val >> 8) | (val << 8);
}
static struct i2c_driver w83781d_driver = { static struct i2c_driver w83781d_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "w83781d", .name = "w83781d",
...@@ -620,73 +616,7 @@ show_fan_div_reg(struct device *dev, char *buf, int nr) ...@@ -620,73 +616,7 @@ show_fan_div_reg(struct device *dev, char *buf, int nr)
least suprise; the user doesn't expect the fan minimum to change just least suprise; the user doesn't expect the fan minimum to change just
because the divisor changed. */ because the divisor changed. */
static ssize_t static ssize_t
store_regs_fan_div_1(struct device *dev, const char *buf, size_t count) store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct w83781d_data *data = i2c_get_clientdata(client);
unsigned long min;
u8 reg;
/* Save fan_min */
min = FAN_FROM_REG(data->fan_min[0],
DIV_FROM_REG(data->fan_div[0]));
data->fan_div[0] = DIV_TO_REG(simple_strtoul(buf, NULL, 10),
data->type);
reg = w83781d_read_value(client, W83781D_REG_VID_FANDIV) & 0xcf;
reg |= (data->fan_div[0] & 0x03) << 4;
w83781d_write_value(client, W83781D_REG_VID_FANDIV, reg);
/* w83781d and as99127f don't have extended divisor bits */
if (data->type != w83781d && data->type != as99127f) {
reg = w83781d_read_value(client, W83781D_REG_VBAT) & 0xdf;
reg |= (data->fan_div[0] & 0x04) << 3;
w83781d_write_value(client, W83781D_REG_VBAT, reg);
}
/* Restore fan_min */
data->fan_min[0] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[0]));
w83781d_write_value(client, W83781D_REG_FAN_MIN(1), data->fan_min[0]);
return count;
}
static ssize_t
store_regs_fan_div_2(struct device *dev, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct w83781d_data *data = i2c_get_clientdata(client);
unsigned long min;
u8 reg;
/* Save fan_min */
min = FAN_FROM_REG(data->fan_min[1],
DIV_FROM_REG(data->fan_div[1]));
data->fan_div[1] = DIV_TO_REG(simple_strtoul(buf, NULL, 10),
data->type);
reg = w83781d_read_value(client, W83781D_REG_VID_FANDIV) & 0x3f;
reg |= (data->fan_div[1] & 0x03) << 6;
w83781d_write_value(client, W83781D_REG_VID_FANDIV, reg);
/* w83781d and as99127f don't have extended divisor bits */
if (data->type != w83781d && data->type != as99127f) {
reg = w83781d_read_value(client, W83781D_REG_VBAT) & 0xbf;
reg |= (data->fan_div[1] & 0x04) << 4;
w83781d_write_value(client, W83781D_REG_VBAT, reg);
}
/* Restore fan_min */
data->fan_min[1] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[1]));
w83781d_write_value(client, W83781D_REG_FAN_MIN(2), data->fan_min[1]);
return count;
}
static ssize_t
store_regs_fan_div_3(struct device *dev, const char *buf, size_t count)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct w83781d_data *data = i2c_get_clientdata(client); struct w83781d_data *data = i2c_get_clientdata(client);
...@@ -694,26 +624,28 @@ store_regs_fan_div_3(struct device *dev, const char *buf, size_t count) ...@@ -694,26 +624,28 @@ store_regs_fan_div_3(struct device *dev, const char *buf, size_t count)
u8 reg; u8 reg;
/* Save fan_min */ /* Save fan_min */
min = FAN_FROM_REG(data->fan_min[2], min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[2])); DIV_FROM_REG(data->fan_div[nr]));
data->fan_div[2] = DIV_TO_REG(simple_strtoul(buf, NULL, 10), data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10),
data->type); data->type);
reg = w83781d_read_value(client, W83781D_REG_PIN) & 0x3f; reg = (w83781d_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
reg |= (data->fan_div[2] & 0x03) << 6; & (nr==0 ? 0xcf : 0x3f))
w83781d_write_value(client, W83781D_REG_PIN, reg); | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));
w83781d_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
/* w83781d and as99127f don't have extended divisor bits */ /* w83781d and as99127f don't have extended divisor bits */
if (data->type != w83781d && data->type != as99127f) { if (data->type != w83781d && data->type != as99127f) {
reg = w83781d_read_value(client, W83781D_REG_VBAT) & 0x7f; reg = (w83781d_read_value(client, W83781D_REG_VBAT)
reg |= (data->fan_div[2] & 0x04) << 5; & ~(1 << (5 + nr)))
| ((data->fan_div[nr] & 0x04) << (3 + nr));
w83781d_write_value(client, W83781D_REG_VBAT, reg); w83781d_write_value(client, W83781D_REG_VBAT, reg);
} }
/* Restore fan_min */ /* Restore fan_min */
data->fan_min[2] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[2])); data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
w83781d_write_value(client, W83781D_REG_FAN_MIN(3), data->fan_min[2]); w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
return count; return count;
} }
...@@ -723,6 +655,10 @@ static ssize_t show_regs_fan_div_##offset (struct device *dev, char *buf) \ ...@@ -723,6 +655,10 @@ static ssize_t show_regs_fan_div_##offset (struct device *dev, char *buf) \
{ \ { \
return show_fan_div_reg(dev, buf, offset); \ return show_fan_div_reg(dev, buf, offset); \
} \ } \
static ssize_t store_regs_fan_div_##offset (struct device *dev, const char *buf, size_t count) \
{ \
return store_fan_div_reg(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset) static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset)
sysfs_fan_div(1); sysfs_fan_div(1);
...@@ -734,7 +670,6 @@ do { \ ...@@ -734,7 +670,6 @@ do { \
device_create_file(&client->dev, &dev_attr_fan##offset##_div); \ device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
} while (0) } while (0)
/* w83697hf only has two fans */
static ssize_t static ssize_t
show_pwm_reg(struct device *dev, char *buf, int nr) show_pwm_reg(struct device *dev, char *buf, int nr)
{ {
...@@ -742,7 +677,6 @@ show_pwm_reg(struct device *dev, char *buf, int nr) ...@@ -742,7 +677,6 @@ show_pwm_reg(struct device *dev, char *buf, int nr)
return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1])); return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1]));
} }
/* w83697hf only has two fans */
static ssize_t static ssize_t
show_pwmenable_reg(struct device *dev, char *buf, int nr) show_pwmenable_reg(struct device *dev, char *buf, int nr)
{ {
...@@ -770,38 +704,26 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr) ...@@ -770,38 +704,26 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct w83781d_data *data = i2c_get_clientdata(client); struct w83781d_data *data = i2c_get_clientdata(client);
u32 val, j, k; u32 val, reg;
val = simple_strtoul(buf, NULL, 10); val = simple_strtoul(buf, NULL, 10);
/* only PWM2 can be enabled/disabled */ switch (val) {
if (nr == 2) { case 0:
j = w83781d_read_value(client, W83781D_REG_PWMCLK12); case 1:
k = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); reg = w83781d_read_value(client, W83781D_REG_PWMCLK12);
w83781d_write_value(client, W83781D_REG_PWMCLK12,
(reg & 0xf7) | (val << 3));
if (val > 0) { reg = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
if (!(j & 0x08)) w83781d_write_value(client, W83781D_REG_BEEP_CONFIG,
w83781d_write_value(client, (reg & 0xef) | (!val << 4));
W83781D_REG_PWMCLK12,
j | 0x08);
if (k & 0x10)
w83781d_write_value(client,
W83781D_REG_BEEP_CONFIG,
k & 0xef);
data->pwmenable[1] = 1; data->pwmenable[nr - 1] = val;
} else { break;
if (j & 0x08)
w83781d_write_value(client,
W83781D_REG_PWMCLK12,
j & 0xf7);
if (!(k & 0x10))
w83781d_write_value(client,
W83781D_REG_BEEP_CONFIG,
j | 0x10);
data->pwmenable[1] = 0; default:
} return -EINVAL;
} }
return count; return count;
...@@ -1177,16 +1099,13 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1177,16 +1099,13 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
But it allows us to access w83781d_{read,write}_value. */ But it allows us to access w83781d_{read,write}_value. */
if (!(new_client = kmalloc(sizeof (struct i2c_client) + if (!(data = kmalloc(sizeof(struct w83781d_data), GFP_KERNEL))) {
sizeof (struct w83781d_data), GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto ERROR1; goto ERROR1;
} }
memset(data, 0, sizeof(struct w83781d_data));
memset(new_client, 0x00, sizeof (struct i2c_client) + new_client = &data->client;
sizeof (struct w83781d_data));
data = (struct w83781d_data *) (new_client + 1);
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
init_MUTEX(&data->lock); init_MUTEX(&data->lock);
...@@ -1312,6 +1231,15 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1312,6 +1231,15 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
/* Initialize the chip */ /* Initialize the chip */
w83781d_init_client(new_client); w83781d_init_client(new_client);
/* A few vars need to be filled upon startup */
for (i = 1; i <= 3; i++) {
data->fan_min[i - 1] = w83781d_read_value(new_client,
W83781D_REG_FAN_MIN(i));
}
if (kind != w83781d && kind != as99127f)
for (i = 0; i < 4; i++)
data->pwmenable[i] = 1;
/* Register sysfs hooks */ /* Register sysfs hooks */
device_create_file_in(new_client, 0); device_create_file_in(new_client, 0);
if (kind != w83783s && kind != w83697hf) if (kind != w83783s && kind != w83697hf)
...@@ -1351,7 +1279,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1351,7 +1279,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file_beep(new_client); device_create_file_beep(new_client);
if (kind != w83781d) { if (kind != w83781d && kind != as99127f) {
device_create_file_pwm(new_client, 1); device_create_file_pwm(new_client, 1);
device_create_file_pwm(new_client, 2); device_create_file_pwm(new_client, 2);
device_create_file_pwmenable(new_client, 2); device_create_file_pwmenable(new_client, 2);
...@@ -1380,7 +1308,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1380,7 +1308,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
ERROR3: ERROR3:
i2c_detach_client(new_client); i2c_detach_client(new_client);
ERROR2: ERROR2:
kfree(new_client); kfree(data);
ERROR1: ERROR1:
if (is_isa) if (is_isa)
release_region(address, W83781D_EXTENT); release_region(address, W83781D_EXTENT);
...@@ -1402,7 +1330,7 @@ w83781d_detach_client(struct i2c_client *client) ...@@ -1402,7 +1330,7 @@ w83781d_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
...@@ -1461,20 +1389,17 @@ w83781d_read_value(struct i2c_client *client, u16 reg) ...@@ -1461,20 +1389,17 @@ w83781d_read_value(struct i2c_client *client, u16 reg)
/* convert from ISA to LM75 I2C addresses */ /* convert from ISA to LM75 I2C addresses */
switch (reg & 0xff) { switch (reg & 0xff) {
case 0x50: /* TEMP */ case 0x50: /* TEMP */
res = res = swab16(i2c_smbus_read_word_data(cl, 0));
swap_bytes(i2c_smbus_read_word_data(cl, 0));
break; break;
case 0x52: /* CONFIG */ case 0x52: /* CONFIG */
res = i2c_smbus_read_byte_data(cl, 1); res = i2c_smbus_read_byte_data(cl, 1);
break; break;
case 0x53: /* HYST */ case 0x53: /* HYST */
res = res = swab16(i2c_smbus_read_word_data(cl, 2));
swap_bytes(i2c_smbus_read_word_data(cl, 2));
break; break;
case 0x55: /* OVER */ case 0x55: /* OVER */
default: default:
res = res = swab16(i2c_smbus_read_word_data(cl, 3));
swap_bytes(i2c_smbus_read_word_data(cl, 3));
break; break;
} }
} }
...@@ -1535,12 +1460,10 @@ w83781d_write_value(struct i2c_client *client, u16 reg, u16 value) ...@@ -1535,12 +1460,10 @@ w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
i2c_smbus_write_byte_data(cl, 1, value & 0xff); i2c_smbus_write_byte_data(cl, 1, value & 0xff);
break; break;
case 0x53: /* HYST */ case 0x53: /* HYST */
i2c_smbus_write_word_data(cl, 2, i2c_smbus_write_word_data(cl, 2, swab16(value));
swap_bytes(value));
break; break;
case 0x55: /* OVER */ case 0x55: /* OVER */
i2c_smbus_write_word_data(cl, 3, i2c_smbus_write_word_data(cl, 3, swab16(value));
swap_bytes(value));
break; break;
} }
} }
...@@ -1644,9 +1567,6 @@ w83781d_init_client(struct i2c_client *client) ...@@ -1644,9 +1567,6 @@ w83781d_init_client(struct i2c_client *client)
if (!(i & 0x40)) if (!(i & 0x40))
w83781d_write_value(client, W83781D_REG_IRQ, w83781d_write_value(client, W83781D_REG_IRQ,
i | 0x40); i | 0x40);
for (i = 0; i < 3; i++)
data->pwmenable[i] = 1;
} }
} }
...@@ -1690,20 +1610,19 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) ...@@ -1690,20 +1610,19 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
data->fan_min[i - 1] = data->fan_min[i - 1] =
w83781d_read_value(client, W83781D_REG_FAN_MIN(i)); w83781d_read_value(client, W83781D_REG_FAN_MIN(i));
} }
if (data->type != w83781d) { if (data->type != w83781d && data->type != as99127f) {
for (i = 1; i <= 4; i++) { for (i = 1; i <= 4; i++) {
data->pwm[i - 1] = data->pwm[i - 1] =
w83781d_read_value(client, w83781d_read_value(client,
W83781D_REG_PWM(i)); W83781D_REG_PWM(i));
if (((data->type == w83783s) if ((data->type != w83782d
|| (data->type == w83627hf) || i2c_is_isa_client(client))
|| (data->type == as99127f)
|| (data->type == w83697hf)
|| ((data->type == w83782d)
&& i2c_is_isa_client(client)))
&& i == 2) && i == 2)
break; break;
} }
/* Only PWM2 can be disabled */
data->pwmenable[1] = (w83781d_read_value(client,
W83781D_REG_PWMCLK12) & 0x08) >> 3;
} }
data->temp = w83781d_read_value(client, W83781D_REG_TEMP(1)); data->temp = w83781d_read_value(client, W83781D_REG_TEMP(1));
......
...@@ -105,7 +105,7 @@ static struct i2c_driver w83l785ts_driver = { ...@@ -105,7 +105,7 @@ static struct i2c_driver w83l785ts_driver = {
*/ */
struct w83l785ts_data { struct w83l785ts_data {
struct i2c_client client;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -164,18 +164,16 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -164,18 +164,16 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit; goto exit;
if (!(new_client = kmalloc(sizeof(struct i2c_client) + if (!(data = kmalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) {
sizeof(struct w83l785ts_data), GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) + memset(data, 0, sizeof(struct w83l785ts_data));
sizeof(struct w83l785ts_data));
/* The W83L785TS-specific data is placed right after the common I2C /* The common I2C client data is placed right before the
* client data. */ * W83L785TS-specific data. */
data = (struct w83l785ts_data *) (new_client + 1); new_client = &data->client;
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = address; new_client->addr = address;
new_client->adapter = adapter; new_client->adapter = adapter;
...@@ -255,7 +253,7 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -255,7 +253,7 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_free: exit_free:
kfree(new_client); kfree(data);
exit: exit:
return err; return err;
} }
...@@ -270,7 +268,7 @@ static int w83l785ts_detach_client(struct i2c_client *client) ...@@ -270,7 +268,7 @@ static int w83l785ts_detach_client(struct i2c_client *client)
return err; return err;
} }
kfree(client); kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
...@@ -997,6 +997,7 @@ ...@@ -997,6 +997,7 @@
#define PCI_DEVICE_ID_AL_M1531 0x1531 #define PCI_DEVICE_ID_AL_M1531 0x1531
#define PCI_DEVICE_ID_AL_M1533 0x1533 #define PCI_DEVICE_ID_AL_M1533 0x1533
#define PCI_DEVICE_ID_AL_M1541 0x1541 #define PCI_DEVICE_ID_AL_M1541 0x1541
#define PCI_DEVICE_ID_AL_M1563 0x1563
#define PCI_DEVICE_ID_AL_M1621 0x1621 #define PCI_DEVICE_ID_AL_M1621 0x1621
#define PCI_DEVICE_ID_AL_M1631 0x1631 #define PCI_DEVICE_ID_AL_M1631 0x1631
#define PCI_DEVICE_ID_AL_M1632 0x1632 #define PCI_DEVICE_ID_AL_M1632 0x1632
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment