Commit 8566cfc9 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6

parents 7bdb2b6a 77ae8455
...@@ -2,16 +2,11 @@ Kernel driver lm78 ...@@ -2,16 +2,11 @@ Kernel driver lm78
================== ==================
Supported chips: Supported chips:
* National Semiconductor LM78 * National Semiconductor LM78 / LM78-J
Prefix: 'lm78' Prefix: 'lm78'
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports) Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
Datasheet: Publicly available at the National Semiconductor website Datasheet: Publicly available at the National Semiconductor website
http://www.national.com/ http://www.national.com/
* National Semiconductor LM78-J
Prefix: 'lm78-j'
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
Datasheet: Publicly available at the National Semiconductor website
http://www.national.com/
* National Semiconductor LM79 * National Semiconductor LM79
Prefix: 'lm79' Prefix: 'lm79'
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports) Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
......
Kernel driver w83792d
=====================
Supported chips:
* Winbond W83792D
Prefix: 'w83792d'
Addresses scanned: I2C 0x2c - 0x2f
Datasheet: http://www.winbond.com.tw/E-WINBONDHTM/partner/PDFresult.asp?Pname=1035
Author: Chunhao Huang
Contact: DZShen <DZShen@Winbond.com.tw>
Module Parameters
-----------------
* init int
(default 1)
Use 'init=0' to bypass initializing the chip.
Try this if your computer crashes when you load the module.
* force_subclients=bus,caddr,saddr,saddr
This is used to force the i2c addresses for subclients of
a certain chip. Example usage is `force_subclients=0,0x2f,0x4a,0x4b'
to force the subclients of chip 0x2f on bus 0 to i2c addresses
0x4a and 0x4b.
Description
-----------
This driver implements support for the Winbond W83792AD/D.
Detection of the chip can sometimes be foiled because it can be in an
internal state that allows no clean access (Bank with ID register is not
currently selected). If you know the address of the chip, use a 'force'
parameter; this will put it into a more well-behaved state first.
The driver implements three temperature sensors, seven fan rotation speed
sensors, nine voltage sensors, and two automatic fan regulation
strategies called: Smart Fan I (Thermal Cruise mode) and Smart Fan II.
Automatic fan control mode is possible only for fan1-fan3. Fan4-fan7 can run
synchronized with selected fan (fan1-fan3). This functionality and manual PWM
control for fan4-fan7 is not yet implemented.
Temperatures are measured in degrees Celsius and measurement resolution is 1
degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
the temperature gets higher than the Overtemperature Shutdown value; it stays
on until the temperature falls below the Hysteresis value.
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
triggered if the rotation speed has dropped below a programmable limit. Fan
readings can be divided by a programmable divider (1, 2, 4, 8, 16, 32, 64 or
128) to give the readings more range or accuracy.
Voltage sensors (also known as IN sensors) report their values in millivolts.
An alarm is triggered if the voltage has crossed a programmable minimum
or maximum limit.
Alarms are provided as output from "realtime status register". Following bits
are defined:
bit - alarm on:
0 - in0
1 - in1
2 - temp1
3 - temp2
4 - temp3
5 - fan1
6 - fan2
7 - fan3
8 - in2
9 - in3
10 - in4
11 - in5
12 - in6
13 - VID change
14 - chassis
15 - fan7
16 - tart1
17 - tart2
18 - tart3
19 - in7
20 - in8
21 - fan4
22 - fan5
23 - fan6
Tart will be asserted while target temperature cannot be achieved after 3 minutes
of full speed rotation of corresponding fan.
In addition to the alarms described above, there is a CHAS alarm on the chips
which triggers if your computer case is open (This one is latched, contrary
to realtime alarms).
The chips only update values each 3 seconds; reading them more often will
do no harm, but will return 'old' values.
W83792D PROBLEMS
----------------
Known problems:
- This driver is only for Winbond W83792D C version device, there
are also some motherboards with B version W83792D device. The
calculation method to in6-in7(measured value, limits) is a little
different between C and B version. C or B version can be identified
by CR[0x49h].
- The function of vid and vrm has not been finished, because I'm NOT
very familiar with them. Adding support is welcome.
  - The function of chassis open detection needs more tests.
- If you have ASUS server board and chip was not found: Then you will
need to upgrade to latest (or beta) BIOS. If it does not help please
contact us.
Fan control
-----------
Manual mode
-----------
Works as expected. You just need to specify desired PWM/DC value (fan speed)
in appropriate pwm# file.
Thermal cruise
--------------
In this mode, W83792D provides the Smart Fan system to automatically control
fan speed to keep the temperatures of CPU and the system within specific
range. At first a wanted temperature and interval must be set. This is done
via thermal_cruise# file. The tolerance# file serves to create T +- tolerance
interval. The fan speed will be lowered as long as the current temperature
remains below the thermal_cruise# +- tolerance# value. Once the temperature
exceeds the high limit (T+tolerance), the fan will be turned on with a
specific speed set by pwm# and automatically controlled its PWM duty cycle
with the temperature varying. Three conditions may occur:
(1) If the temperature still exceeds the high limit, PWM duty
cycle will increase slowly.
(2) If the temperature goes below the high limit, but still above the low
limit (T-tolerance), the fan speed will be fixed at the current speed because
the temperature is in the target range.
(3) If the temperature goes below the low limit, PWM duty cycle will decrease
slowly to 0 or a preset stop value until the temperature exceeds the low
limit. (The preset stop value handling is not yet implemented in driver)
Smart Fan II
------------
W83792D also provides a special mode for fan. Four temperature points are
available. When related temperature sensors detects the temperature in preset
temperature region (sf2_point@_fan# +- tolerance#) it will cause fans to run
on programmed value from sf2_level@_fan#. You need to set four temperatures
for each fan.
/sys files
----------
pwm[1-3] - this file stores PWM duty cycle or DC value (fan speed) in range:
0 (stop) to 255 (full)
pwm[1-3]_enable - this file controls mode of fan/temperature control:
* 0 Disabled
* 1 Manual mode
* 2 Smart Fan II
* 3 Thermal Cruise
pwm[1-3]_mode - Select PWM of DC mode
* 0 DC
* 1 PWM
thermal_cruise[1-3] - Selects the desired temperature for cruise (degC)
tolerance[1-3] - Value in degrees of Celsius (degC) for +- T
sf2_point[1-4]_fan[1-3] - four temperature points for each fan for Smart Fan II
sf2_level[1-3]_fan[1-3] - three PWM/DC levels for each fan for Smart Fan II
...@@ -4,22 +4,13 @@ Kernel driver max6875 ...@@ -4,22 +4,13 @@ Kernel driver max6875
Supported chips: Supported chips:
* Maxim MAX6874, MAX6875 * Maxim MAX6874, MAX6875
Prefix: 'max6875' Prefix: 'max6875'
Addresses scanned: 0x50, 0x52 Addresses scanned: None (see below)
Datasheet: Datasheet:
http://pdfserv.maxim-ic.com/en/ds/MAX6874-MAX6875.pdf http://pdfserv.maxim-ic.com/en/ds/MAX6874-MAX6875.pdf
Author: Ben Gardner <bgardner@wabtec.com> Author: Ben Gardner <bgardner@wabtec.com>
Module Parameters
-----------------
* allow_write int
Set to non-zero to enable write permission:
*0: Read only
1: Read and write
Description Description
----------- -----------
...@@ -33,34 +24,85 @@ registers. ...@@ -33,34 +24,85 @@ registers.
The Maxim MAX6874 is a similar, mostly compatible device, with more intputs The Maxim MAX6874 is a similar, mostly compatible device, with more intputs
and outputs: and outputs:
vin gpi vout vin gpi vout
MAX6874 6 4 8 MAX6874 6 4 8
MAX6875 4 3 5 MAX6875 4 3 5
MAX6874 chips can have four different addresses (as opposed to only two for See the datasheet for more information.
the MAX6875). The additional addresses (0x54 and 0x56) are not probed by
this driver by default, but the probe module parameter can be used if
needed.
See the datasheet for details on how to program the EEPROM.
Sysfs entries Sysfs entries
------------- -------------
eeprom_user - 512 bytes of user-defined EEPROM space. Only writable if eeprom - 512 bytes of user-defined EEPROM space.
allow_write was set and register 0x43 is 0.
eeprom_config - 70 bytes of config EEPROM. Note that changes will not get
loaded into register space until a power cycle or device reset.
reg_config - 70 bytes of register space. Any changes take affect immediately.
General Remarks General Remarks
--------------- ---------------
A typical application will require that the EEPROMs be programmed once and Valid addresses for the MAX6875 are 0x50 and 0x52.
never altered afterwards. Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56.
The driver does not probe any address, so you must force the address.
Example:
$ modprobe max6875 force=0,0x50
The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple
addresses. For example, for address 0x50, it also reserves 0x51.
The even-address instance is called 'max6875', the odd one is 'max6875 subclient'.
Programming the chip using i2c-dev
----------------------------------
Use the i2c-dev interface to access and program the chips.
Reads and writes are performed differently depending on the address range.
The configuration registers are at addresses 0x00 - 0x45.
Use i2c_smbus_write_byte_data() to write a register and
i2c_smbus_read_byte_data() to read a register.
The command is the register number.
Examples:
To write a 1 to register 0x45:
i2c_smbus_write_byte_data(fd, 0x45, 1);
To read register 0x45:
value = i2c_smbus_read_byte_data(fd, 0x45);
The configuration EEPROM is at addresses 0x8000 - 0x8045.
The user EEPROM is at addresses 0x8100 - 0x82ff.
Use i2c_smbus_write_word_data() to write a byte to EEPROM.
The command is the upper byte of the address: 0x80, 0x81, or 0x82.
The data word is the lower part of the address or'd with data << 8.
cmd = address >> 8;
val = (address & 0xff) | (data << 8);
Example:
To write 0x5a to address 0x8003:
i2c_smbus_write_word_data(fd, 0x80, 0x5a03);
Reading data from the EEPROM is a little more complicated.
Use i2c_smbus_write_byte_data() to set the read address and then
i2c_smbus_read_byte() or i2c_smbus_read_i2c_block_data() to read the data.
Example:
To read data starting at offset 0x8100, first set the address:
i2c_smbus_write_byte_data(fd, 0x81, 0x00);
And then read the data
value = i2c_smbus_read_byte(fd);
or
count = i2c_smbus_read_i2c_block_data(fd, 0x84, buffer);
The block read should read 16 bytes.
0x84 is the block read command.
See the datasheet for more details.
...@@ -115,7 +115,7 @@ CHECKING THROUGH /DEV ...@@ -115,7 +115,7 @@ CHECKING THROUGH /DEV
If you try to access an adapter from a userspace program, you will have If you try to access an adapter from a userspace program, you will have
to use the /dev interface. You will still have to check whether the to use the /dev interface. You will still have to check whether the
functionality you need is supported, of course. This is done using functionality you need is supported, of course. This is done using
the I2C_FUNCS ioctl. An example, adapted from the lm_sensors i2c_detect the I2C_FUNCS ioctl. An example, adapted from the lm_sensors i2cdetect
program, is below: program, is below:
int file; int file;
......
Revision 4, 2004-03-30 Revision 5, 2005-07-29
Jean Delvare <khali@linux-fr.org> Jean Delvare <khali@linux-fr.org>
Greg KH <greg@kroah.com> Greg KH <greg@kroah.com>
...@@ -17,20 +17,22 @@ yours for best results. ...@@ -17,20 +17,22 @@ yours for best results.
Technical changes: Technical changes:
* [Includes] Get rid of "version.h". Replace <linux/i2c-proc.h> with * [Includes] Get rid of "version.h" and <linux/i2c-proc.h>.
<linux/i2c-sensor.h>. Includes typically look like that: Includes typically look like that:
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h> /* for hardware monitoring drivers */
#include <linux/i2c-vid.h> /* if you need VRM support */ #include <linux/hwmon-sysfs.h>
#include <linux/hwmon-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 */
Please respect this inclusion order. Some extra headers may be Please respect this inclusion order. Some extra headers may be
required for a given driver (e.g. "lm75.h"). 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, ISA addresses
becomes I2C_CLIENT_ISA_END. are no more handled by the i2c core.
SENSORS_INSMOD_<n> becomes I2C_CLIENT_INSMOD_<n>.
* [Client data] Get rid of sysctl_id. Try using standard names for * [Client data] Get rid of sysctl_id. Try using standard names for
register values (for example, temp_os becomes temp_max). You're register values (for example, temp_os becomes temp_max). You're
...@@ -66,13 +68,15 @@ Technical changes: ...@@ -66,13 +68,15 @@ Technical changes:
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
ISA-only drivers of course don't need this. ISA-only drivers of course don't need this.
Call i2c_probe() instead of i2c_detect().
* [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"). (typically the driver name, e.g. "lm75").
In i2c-only drivers, drop the i2c_is_isa_adapter check, it's In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
useless. useless. Same for isa-only drivers, as the test would always be
true. Only hybrid drivers (which are quite rare) still need it.
The errorN labels are reduced to the number needed. If that number The errorN labels are reduced to the number needed. If that number
is 2 (i2c-only drivers), it is advised that the labels are named is 2 (i2c-only drivers), it is advised that the labels are named
exit and exit_free. For i2c+isa drivers, labels should be named exit and exit_free. For i2c+isa drivers, labels should be named
...@@ -86,6 +90,8 @@ Technical changes: ...@@ -86,6 +90,8 @@ 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.
Drop client->id. Drop client->id.
Drop any 24RF08 corruption prevention you find, as this is now done
at the i2c-core level, and doing it twice voids it.
* [Init] Limits must not be set by the driver (can be done later in * [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 user-space). Chip should not be reset default (although a module
...@@ -93,7 +99,8 @@ Technical changes: ...@@ -93,7 +99,8 @@ Technical changes:
limited to the strictly necessary steps. 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. Do not log an error message if
i2c_detach_client fails, as i2c-core will now do it for you.
* [Update] Don't access client->data directly, use * [Update] Don't access client->data directly, use
i2c_get_clientdata(client) instead. i2c_get_clientdata(client) instead.
......
...@@ -148,15 +148,15 @@ are defined in i2c.h to help you support them, as well as a generic ...@@ -148,15 +148,15 @@ are defined in i2c.h to help you support them, as well as a generic
detection algorithm. detection algorithm.
You do not have to use this parameter interface; but don't try to use You do not have to use this parameter interface; but don't try to use
function i2c_probe() (or i2c_detect()) if you don't. function i2c_probe() if you don't.
NOTE: If you want to write a `sensors' driver, the interface is slightly NOTE: If you want to write a `sensors' driver, the interface is slightly
different! See below. different! See below.
Probing classes (i2c) Probing classes
--------------------- ---------------
All parameters are given as lists of unsigned 16-bit integers. Lists are All parameters are given as lists of unsigned 16-bit integers. Lists are
terminated by I2C_CLIENT_END. terminated by I2C_CLIENT_END.
...@@ -171,12 +171,18 @@ The following lists are used internally: ...@@ -171,12 +171,18 @@ The following lists are used internally:
ignore: insmod parameter. ignore: insmod parameter.
A list of pairs. The first value is a bus number (-1 for any I2C bus), A list of pairs. The first value is a bus number (-1 for any I2C bus),
the second is the I2C address. These addresses are never probed. the second is the I2C address. These addresses are never probed.
This parameter overrules 'normal' and 'probe', but not the 'force' lists. This parameter overrules the 'normal_i2c' list only.
force: insmod parameter. force: insmod parameter.
A list of pairs. The first value is a bus number (-1 for any I2C bus), A list of pairs. The first value is a bus number (-1 for any I2C bus),
the second is the I2C address. A device is blindly assumed to be on the second is the I2C address. A device is blindly assumed to be on
the given address, no probing is done. the given address, no probing is done.
Additionally, kind-specific force lists may optionally be defined if
the driver supports several chip kinds. They are grouped in a
NULL-terminated list of pointers named forces, those first element if the
generic force list mentioned above. Each additional list correspond to an
insmod parameter of the form force_<kind>.
Fortunately, as a module writer, you just have to define the `normal_i2c' Fortunately, as a module writer, you just have to define the `normal_i2c'
parameter. The complete declaration could look like this: parameter. The complete declaration could look like this:
...@@ -186,66 +192,17 @@ parameter. The complete declaration could look like this: ...@@ -186,66 +192,17 @@ parameter. The complete declaration could look like this:
/* Magic definition of all other variables and things */ /* Magic definition of all other variables and things */
I2C_CLIENT_INSMOD; I2C_CLIENT_INSMOD;
/* Or, if your driver supports, say, 2 kind of devices: */
I2C_CLIENT_INSMOD_2(foo, bar);
If you use the multi-kind form, an enum will be defined for you:
enum chips { any_chip, foo, bar, ... }
You can then (and certainly should) use it in the driver code.
Note that you *have* to call the defined variable `normal_i2c', Note that you *have* to call the defined variable `normal_i2c',
without any prefix! without any prefix!
Probing classes (sensors)
-------------------------
If you write a `sensors' driver, you use a slightly different interface.
As well as I2C addresses, we have to cope with ISA addresses. Also, we
use a enum of chip types. Don't forget to include `sensors.h'.
The following lists are used internally. They are all lists of integers.
normal_i2c: filled in by the module writer. Terminated by SENSORS_I2C_END.
A list of I2C addresses which should normally be examined.
normal_isa: filled in by the module writer. Terminated by SENSORS_ISA_END.
A list of ISA addresses which should normally be examined.
probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
the ISA bus, -1 for any I2C bus), the second is the address. These
addresses are also probed, as if they were in the 'normal' list.
ignore: insmod parameter. Initialize this list with SENSORS_I2C_END values.
A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
the ISA bus, -1 for any I2C bus), the second is the I2C address. These
addresses are never probed. This parameter overrules 'normal' and
'probe', but not the 'force' lists.
Also used is a list of pointers to sensors_force_data structures:
force_data: insmod parameters. A list, ending with an element of which
the force field is NULL.
Each element contains the type of chip and a list of pairs.
The first value is a bus number (SENSORS_ISA_BUS for the ISA bus,
-1 for any I2C bus), the second is the address.
These are automatically translated to insmod variables of the form
force_foo.
So we have a generic insmod variabled `force', and chip-specific variables
`force_CHIPNAME'.
Fortunately, as a module writer, you just have to define the `normal_i2c'
and `normal_isa' parameters, and define what chip names are used.
The complete declaration could look like this:
/* Scan i2c addresses 0x37, and 0x48 to 0x4f */
static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
/* Scan ISA address 0x290 */
static unsigned int normal_isa[] = {0x0290,SENSORS_ISA_END};
/* Define chips foo and bar, as well as all module parameters and things */
SENSORS_INSMOD_2(foo,bar);
If you have one chip, you use macro SENSORS_INSMOD_1(chip), if you have 2
you use macro SENSORS_INSMOD_2(chip1,chip2), etc. If you do not want to
bother with chip types, you can use SENSORS_INSMOD_0.
A enum is automatically defined as follows:
enum chips { any_chip, chip1, chip2, ... }
Attaching to an adapter Attaching to an adapter
----------------------- -----------------------
...@@ -264,17 +221,10 @@ detected at a specific address, another callback is called. ...@@ -264,17 +221,10 @@ detected at a specific address, another callback is called.
return i2c_probe(adapter,&addr_data,&foo_detect_client); return i2c_probe(adapter,&addr_data,&foo_detect_client);
} }
For `sensors' drivers, use the i2c_detect function instead:
int foo_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_detect(adapter,&addr_data,&foo_detect_client);
}
Remember, structure `addr_data' is defined by the macros explained above, Remember, structure `addr_data' is defined by the macros explained above,
so you do not have to define it yourself. so you do not have to define it yourself.
The i2c_probe or i2c_detect function will call the foo_detect_client The i2c_probe function will call the foo_detect_client
function only for those i2c addresses that actually have a device on function only for those i2c addresses that actually have a device on
them (unless a `force' parameter was used). In addition, addresses that them (unless a `force' parameter was used). In addition, addresses that
are already in use (by some other registered client) are skipped. are already in use (by some other registered client) are skipped.
...@@ -283,19 +233,18 @@ are already in use (by some other registered client) are skipped. ...@@ -283,19 +233,18 @@ are already in use (by some other registered client) are skipped.
The detect client function The detect client function
-------------------------- --------------------------
The detect client function is called by i2c_probe or i2c_detect. The detect client function is called by i2c_probe. The `kind' parameter
The `kind' parameter contains 0 if this call is due to a `force' contains -1 for a probed detection, 0 for a forced detection, or a positive
parameter, and -1 otherwise (for i2c_detect, it contains 0 if number for a forced detection with a chip type forced.
this call is due to the generic `force' parameter, and the chip type
number if it is due to a specific `force' parameter).
Below, some things are only needed if this is a `sensors' driver. Those Below, some things are only needed if this is a `sensors' driver. Those
parts are between /* SENSORS ONLY START */ and /* SENSORS ONLY END */ parts are between /* SENSORS ONLY START */ and /* SENSORS ONLY END */
markers. markers.
This function should only return an error (any value != 0) if there is Returning an error different from -ENODEV in a detect function will cause
some reason why no more detection should be done anymore. If the the detection to stop: other addresses and adapters won't be scanned.
detection just fails for this address, return 0. This should only be done on fatal or internal errors, such as a memory
shortage or i2c_attach_client failing.
For now, you can ignore the `flags' parameter. It is there for future use. For now, you can ignore the `flags' parameter. It is there for future use.
...@@ -320,11 +269,10 @@ For now, you can ignore the `flags' parameter. It is there for future use. ...@@ -320,11 +269,10 @@ For now, you can ignore the `flags' parameter. It is there for future use.
const char *type_name = ""; const char *type_name = "";
int is_isa = i2c_is_isa_adapter(adapter); int is_isa = i2c_is_isa_adapter(adapter);
if (is_isa) { /* Do this only if the chip can additionally be found on the ISA bus
(hybrid chip). */
/* If this client can't be on the ISA bus at all, we can stop now if (is_isa) {
(call `goto ERROR0'). But for kicks, we will assume it is all
right. */
/* Discard immediately if this ISA range is already used */ /* Discard immediately if this ISA range is already used */
if (check_region(address,FOO_EXTENT)) if (check_region(address,FOO_EXTENT))
...@@ -495,15 +443,13 @@ much simpler than the attachment code, fortunately! ...@@ -495,15 +443,13 @@ much simpler than the attachment code, fortunately!
/* SENSORS ONLY END */ /* SENSORS ONLY END */
/* Try to detach the client from i2c space */ /* Try to detach the client from i2c space */
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client)))
printk("foo.o: Client deregistration failed, client not detached.\n");
return err; return err;
}
/* SENSORS ONLY START */ /* HYBRID SENSORS CHIP ONLY START */
if i2c_is_isa_client(client) if i2c_is_isa_client(client)
release_region(client->addr,LM78_EXTENT); release_region(client->addr,LM78_EXTENT);
/* SENSORS ONLY END */ /* HYBRID SENSORS CHIP ONLY END */
kfree(client); /* Frees client data too, if allocated at the same time */ kfree(client); /* Frees client data too, if allocated at the same time */
return 0; return 0;
......
...@@ -933,6 +933,13 @@ M: khc@pm.waw.pl ...@@ -933,6 +933,13 @@ M: khc@pm.waw.pl
W: http://www.kernel.org/pub/linux/utils/net/hdlc/ W: http://www.kernel.org/pub/linux/utils/net/hdlc/
S: Maintained S: Maintained
HARDWARE MONITORING
P: Jean Delvare
M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.nu/
S: Maintained
HARMONY SOUND DRIVER HARMONY SOUND DRIVER
P: Kyle McMartin P: Kyle McMartin
M: kyle@parisc-linux.org M: kyle@parisc-linux.org
...@@ -1014,7 +1021,7 @@ P: William Irwin ...@@ -1014,7 +1021,7 @@ P: William Irwin
M: wli@holomorphy.com M: wli@holomorphy.com
S: Maintained S: Maintained
I2C AND SENSORS DRIVERS I2C SUBSYSTEM
P: Greg Kroah-Hartman P: Greg Kroah-Hartman
M: greg@kroah.com M: greg@kroah.com
P: Jean Delvare P: Jean Delvare
......
This diff is collapsed.
...@@ -2,9 +2,13 @@ ...@@ -2,9 +2,13 @@
# Makefile for sensor chip drivers. # Makefile for sensor chip drivers.
# #
obj-$(CONFIG_HWMON) += hwmon.o
obj-$(CONFIG_HWMON_VID) += hwmon-vid.o
# asb100, then w83781d go first, as they can override other drivers' addresses. # asb100, then w83781d go first, as they can override other drivers' addresses.
obj-$(CONFIG_SENSORS_ASB100) += asb100.o obj-$(CONFIG_SENSORS_ASB100) += asb100.o
obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o
obj-$(CONFIG_SENSORS_W83792D) += w83792d.o
obj-$(CONFIG_SENSORS_W83781D) += w83781d.o obj-$(CONFIG_SENSORS_W83781D) += w83781d.o
obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
...@@ -32,10 +33,9 @@ static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, ...@@ -32,10 +33,9 @@ static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
0x29, 0x2a, 0x2b, 0x29, 0x2a, 0x2b,
0x4c, 0x4d, 0x4e, 0x4c, 0x4d, 0x4e,
I2C_CLIENT_END }; I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1066); I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1066);
/* adm1021 constants specified below */ /* adm1021 constants specified below */
...@@ -89,6 +89,7 @@ clearing it. Weird, ey? --Phil */ ...@@ -89,6 +89,7 @@ clearing it. Weird, ey? --Phil */
/* Each client has this additional data */ /* Each client has this additional data */
struct adm1021_data { struct adm1021_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
enum chips type; enum chips type;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -185,7 +186,7 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter) ...@@ -185,7 +186,7 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, adm1021_detect); return i2c_probe(adapter, &addr_data, adm1021_detect);
} }
static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
...@@ -196,15 +197,6 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -196,15 +197,6 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
int err = 0; int err = 0;
const char *type_name = ""; const char *type_name = "";
/* Make sure we aren't probing the ISA bus!! This is just a safety check
at this moment; i2c_detect really won't call us. */
#ifdef DEBUG
if (i2c_is_isa_adapter(adapter)) {
dev_dbg(&adapter->dev, "adm1021_detect called for an ISA bus adapter?!?\n");
return 0;
}
#endif
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto error0; goto error0;
...@@ -295,6 +287,12 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -295,6 +287,12 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
adm1021_init_client(new_client); adm1021_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto error2;
}
device_create_file(&new_client->dev, &dev_attr_temp1_max); device_create_file(&new_client->dev, &dev_attr_temp1_max);
device_create_file(&new_client->dev, &dev_attr_temp1_min); device_create_file(&new_client->dev, &dev_attr_temp1_min);
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
...@@ -305,6 +303,8 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -305,6 +303,8 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
error2:
i2c_detach_client(new_client);
error1: error1:
kfree(data); kfree(data);
error0: error0:
...@@ -322,14 +322,15 @@ static void adm1021_init_client(struct i2c_client *client) ...@@ -322,14 +322,15 @@ static void adm1021_init_client(struct i2c_client *client)
static int adm1021_detach_client(struct i2c_client *client) static int adm1021_detach_client(struct i2c_client *client)
{ {
struct adm1021_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, client not detached.\n");
if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -50,8 +50,9 @@ ...@@ -50,8 +50,9 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/i2c-vid.h> #include <linux/hwmon-vid.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -60,13 +61,12 @@ ...@@ -60,13 +61,12 @@
*/ */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* /*
* Insmod parameters * Insmod parameters
*/ */
SENSORS_INSMOD_2(adm1025, ne1619); I2C_CLIENT_INSMOD_2(adm1025, ne1619);
/* /*
* The ADM1025 registers * The ADM1025 registers
...@@ -132,6 +132,7 @@ static struct i2c_driver adm1025_driver = { ...@@ -132,6 +132,7 @@ static struct i2c_driver adm1025_driver = {
struct adm1025_data { struct adm1025_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
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 */
...@@ -312,7 +313,7 @@ static int adm1025_attach_adapter(struct i2c_adapter *adapter) ...@@ -312,7 +313,7 @@ static int adm1025_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, adm1025_detect); return i2c_probe(adapter, &addr_data, adm1025_detect);
} }
/* /*
...@@ -416,6 +417,12 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -416,6 +417,12 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
adm1025_init_client(new_client); adm1025_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
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_in1_input); device_create_file(&new_client->dev, &dev_attr_in1_input);
device_create_file(&new_client->dev, &dev_attr_in2_input); device_create_file(&new_client->dev, &dev_attr_in2_input);
...@@ -452,6 +459,8 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -452,6 +459,8 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -464,7 +473,7 @@ static void adm1025_init_client(struct i2c_client *client) ...@@ -464,7 +473,7 @@ static void adm1025_init_client(struct i2c_client *client)
struct adm1025_data *data = i2c_get_clientdata(client); struct adm1025_data *data = i2c_get_clientdata(client);
int i; int i;
data->vrm = i2c_which_vrm(); data->vrm = vid_which_vrm();
/* /*
* Set high limits * Set high limits
...@@ -502,15 +511,15 @@ static void adm1025_init_client(struct i2c_client *client) ...@@ -502,15 +511,15 @@ static void adm1025_init_client(struct i2c_client *client)
static int adm1025_detach_client(struct i2c_client *client) static int adm1025_detach_client(struct i2c_client *client)
{ {
struct adm1025_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -28,16 +28,16 @@ ...@@ -28,16 +28,16 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/i2c-vid.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_1(adm1026); I2C_CLIENT_INSMOD_1(adm1026);
static int gpio_input[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, static int gpio_input[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1 }; -1, -1, -1, -1, -1, -1, -1, -1 };
...@@ -259,6 +259,7 @@ struct pwm_data { ...@@ -259,6 +259,7 @@ struct pwm_data {
struct adm1026_data { struct adm1026_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -319,13 +320,15 @@ int adm1026_attach_adapter(struct i2c_adapter *adapter) ...@@ -319,13 +320,15 @@ int adm1026_attach_adapter(struct i2c_adapter *adapter)
if (!(adapter->class & I2C_CLASS_HWMON)) { if (!(adapter->class & I2C_CLASS_HWMON)) {
return 0; return 0;
} }
return i2c_detect(adapter, &addr_data, adm1026_detect); return i2c_probe(adapter, &addr_data, adm1026_detect);
} }
int adm1026_detach_client(struct i2c_client *client) int adm1026_detach_client(struct i2c_client *client)
{ {
struct adm1026_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->class_dev);
i2c_detach_client(client); i2c_detach_client(client);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
...@@ -1549,12 +1552,18 @@ int adm1026_detect(struct i2c_adapter *adapter, int address, ...@@ -1549,12 +1552,18 @@ int adm1026_detect(struct i2c_adapter *adapter, int address,
goto exitfree; goto exitfree;
/* Set the VRM version */ /* Set the VRM version */
data->vrm = i2c_which_vrm(); data->vrm = vid_which_vrm();
/* Initialize the ADM1026 chip */ /* Initialize the ADM1026 chip */
adm1026_init_client(new_client); adm1026_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exitdetach;
}
device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr);
...@@ -1690,6 +1699,8 @@ int adm1026_detect(struct i2c_adapter *adapter, int address, ...@@ -1690,6 +1699,8 @@ int adm1026_detect(struct i2c_adapter *adapter, int address,
return 0; return 0;
/* Error out and cleanup code */ /* Error out and cleanup code */
exitdetach:
i2c_detach_client(new_client);
exitfree: exitfree:
kfree(data); kfree(data);
exit: exit:
......
...@@ -26,7 +26,8 @@ ...@@ -26,7 +26,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
/* Following macros takes channel parameter starting from 0 to 2 */ /* Following macros takes channel parameter starting from 0 to 2 */
#define ADM1031_REG_FAN_SPEED(nr) (0x08 + (nr)) #define ADM1031_REG_FAN_SPEED(nr) (0x08 + (nr))
...@@ -59,16 +60,16 @@ ...@@ -59,16 +60,16 @@
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_2(adm1030, adm1031); I2C_CLIENT_INSMOD_2(adm1030, adm1031);
typedef u8 auto_chan_table_t[8][2]; typedef u8 auto_chan_table_t[8][2];
/* Each client has this additional data */ /* Each client has this additional data */
struct adm1031_data { struct adm1031_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
int chip_type; int chip_type;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
...@@ -725,10 +726,10 @@ static int adm1031_attach_adapter(struct i2c_adapter *adapter) ...@@ -725,10 +726,10 @@ static int adm1031_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, adm1031_detect); return i2c_probe(adapter, &addr_data, adm1031_detect);
} }
/* This function is called by i2c_detect */ /* This function is called by i2c_probe */
static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
{ {
struct i2c_client *new_client; struct i2c_client *new_client;
...@@ -788,6 +789,12 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -788,6 +789,12 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
adm1031_init_client(new_client); adm1031_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_fan1_input); device_create_file(&new_client->dev, &dev_attr_fan1_input);
device_create_file(&new_client->dev, &dev_attr_fan1_div); device_create_file(&new_client->dev, &dev_attr_fan1_div);
device_create_file(&new_client->dev, &dev_attr_fan1_min); device_create_file(&new_client->dev, &dev_attr_fan1_min);
...@@ -833,6 +840,8 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -833,6 +840,8 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -841,11 +850,14 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -841,11 +850,14 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
static int adm1031_detach_client(struct i2c_client *client) static int adm1031_detach_client(struct i2c_client *client)
{ {
struct adm1031_data *data = i2c_get_clientdata(client);
int ret; int ret;
hwmon_device_unregister(data->class_dev);
if ((ret = i2c_detach_client(client)) != 0) { if ((ret = i2c_detach_client(client)) != 0) {
return ret; return ret;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -45,17 +45,16 @@ ...@@ -45,17 +45,16 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/i2c-vid.h> #include <linux/hwmon-vid.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
I2C_CLIENT_END }; I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_3(adm9240, ds1780, lm81); I2C_CLIENT_INSMOD_3(adm9240, ds1780, lm81);
/* ADM9240 registers */ /* ADM9240 registers */
#define ADM9240_REG_MAN_ID 0x3e #define ADM9240_REG_MAN_ID 0x3e
...@@ -150,6 +149,7 @@ static struct i2c_driver adm9240_driver = { ...@@ -150,6 +149,7 @@ static struct i2c_driver adm9240_driver = {
struct adm9240_data { struct adm9240_data {
enum chips type; enum chips type;
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; char valid;
unsigned long last_updated_measure; unsigned long last_updated_measure;
...@@ -582,6 +582,12 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -582,6 +582,12 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
adm9240_init_client(new_client); adm9240_init_client(new_client);
/* populate sysfs filesystem */ /* populate sysfs filesystem */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
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);
device_create_file(&new_client->dev, &dev_attr_in0_max); device_create_file(&new_client->dev, &dev_attr_in0_max);
...@@ -615,6 +621,9 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -615,6 +621,9 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_cpu0_vid); device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -625,20 +634,20 @@ static int adm9240_attach_adapter(struct i2c_adapter *adapter) ...@@ -625,20 +634,20 @@ static int adm9240_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, adm9240_detect); return i2c_probe(adapter, &addr_data, adm9240_detect);
} }
static int adm9240_detach_client(struct i2c_client *client) static int adm9240_detach_client(struct i2c_client *client)
{ {
struct adm9240_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
...@@ -648,7 +657,7 @@ static void adm9240_init_client(struct i2c_client *client) ...@@ -648,7 +657,7 @@ static void adm9240_init_client(struct i2c_client *client)
u8 conf = adm9240_read_value(client, ADM9240_REG_CONFIG); u8 conf = adm9240_read_value(client, ADM9240_REG_CONFIG);
u8 mode = adm9240_read_value(client, ADM9240_REG_TEMP_CONF) & 3; u8 mode = adm9240_read_value(client, ADM9240_REG_TEMP_CONF) & 3;
data->vrm = i2c_which_vrm(); /* need this to report vid as mV */ data->vrm = vid_which_vrm(); /* need this to report vid as mV */
dev_info(&client->dev, "Using VRM: %d.%d\n", data->vrm / 10, dev_info(&client->dev, "Using VRM: %d.%d\n", data->vrm / 10,
data->vrm % 10); data->vrm % 10);
......
...@@ -39,8 +39,9 @@ ...@@ -39,8 +39,9 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/i2c-vid.h> #include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include "lm75.h" #include "lm75.h"
...@@ -54,11 +55,8 @@ ...@@ -54,11 +55,8 @@
/* I2C addresses to scan */ /* I2C addresses to scan */
static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
/* ISA addresses to scan (none) */
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_1(asb100); I2C_CLIENT_INSMOD_1(asb100);
I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}"); "{bus, clientaddr, subclientaddr1, subclientaddr2}");
...@@ -183,6 +181,7 @@ static u8 DIV_TO_REG(long val) ...@@ -183,6 +181,7 @@ static u8 DIV_TO_REG(long val)
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 i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -621,7 +620,7 @@ static int asb100_attach_adapter(struct i2c_adapter *adapter) ...@@ -621,7 +620,7 @@ static int asb100_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, asb100_detect); return i2c_probe(adapter, &addr_data, asb100_detect);
} }
static int asb100_detect_subclients(struct i2c_adapter *adapter, int address, static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
...@@ -714,14 +713,6 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -714,14 +713,6 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
struct i2c_client *new_client; struct i2c_client *new_client;
struct asb100_data *data; struct asb100_data *data;
/* asb100 is SMBus only */
if (i2c_is_isa_adapter(adapter)) {
pr_debug("asb100.o: detect failed, "
"cannot attach to legacy adapter!\n");
err = -ENODEV;
goto ERROR0;
}
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
pr_debug("asb100.o: detect failed, " pr_debug("asb100.o: detect failed, "
"smbus byte data not supported!\n"); "smbus byte data not supported!\n");
...@@ -821,6 +812,12 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -821,6 +812,12 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2)); data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2));
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR3;
}
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);
device_create_file_in(new_client, 2); device_create_file_in(new_client, 2);
...@@ -847,6 +844,11 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -847,6 +844,11 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR3:
i2c_detach_client(data->lm75[1]);
i2c_detach_client(data->lm75[0]);
kfree(data->lm75[1]);
kfree(data->lm75[0]);
ERROR2: ERROR2:
i2c_detach_client(new_client); i2c_detach_client(new_client);
ERROR1: ERROR1:
...@@ -857,21 +859,23 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -857,21 +859,23 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
static int asb100_detach_client(struct i2c_client *client) static int asb100_detach_client(struct i2c_client *client)
{ {
struct asb100_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { /* main client */
dev_err(&client->dev, "client deregistration failed; " if (data)
"client not detached.\n"); hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client)))
return err; return err;
}
if (i2c_get_clientdata(client)==NULL) { /* main client */
/* subclients */ if (data)
kfree(data);
/* subclient */
else
kfree(client); kfree(client);
} else {
/* main client */
kfree(i2c_get_clientdata(client));
}
return 0; return 0;
} }
...@@ -969,7 +973,7 @@ static void asb100_init_client(struct i2c_client *client) ...@@ -969,7 +973,7 @@ static void asb100_init_client(struct i2c_client *client)
vid = asb100_read_value(client, ASB100_REG_VID_FANDIV) & 0x0f; vid = asb100_read_value(client, ASB100_REG_VID_FANDIV) & 0x0f;
vid |= (asb100_read_value(client, ASB100_REG_CHIPID) & 0x01) << 4; vid |= (asb100_read_value(client, ASB100_REG_CHIPID) & 0x01) << 4;
data->vrm = i2c_which_vrm(); data->vrm = vid_which_vrm();
vid = vid_from_reg(vid, data->vrm); vid = vid_from_reg(vid, data->vrm);
/* Start monitoring */ /* Start monitoring */
......
...@@ -23,8 +23,9 @@ ...@@ -23,8 +23,9 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/i2c-vid.h> #include <linux/hwmon-vid.h>
#include <linux/err.h>
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("System voltages control via Attansic ATXP1"); MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
...@@ -40,9 +41,8 @@ MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>"); ...@@ -40,9 +41,8 @@ MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
#define ATXP1_GPIO1MASK 0x0f #define ATXP1_GPIO1MASK 0x0f
static unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
SENSORS_INSMOD_1(atxp1); I2C_CLIENT_INSMOD_1(atxp1);
static int atxp1_attach_adapter(struct i2c_adapter * adapter); static int atxp1_attach_adapter(struct i2c_adapter * adapter);
static int atxp1_detach_client(struct i2c_client * client); static int atxp1_detach_client(struct i2c_client * client);
...@@ -59,6 +59,7 @@ static struct i2c_driver atxp1_driver = { ...@@ -59,6 +59,7 @@ static struct i2c_driver atxp1_driver = {
struct atxp1_data { struct atxp1_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
unsigned long last_updated; unsigned long last_updated;
u8 valid; u8 valid;
...@@ -252,7 +253,7 @@ static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2); ...@@ -252,7 +253,7 @@ static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2);
static int atxp1_attach_adapter(struct i2c_adapter *adapter) static int atxp1_attach_adapter(struct i2c_adapter *adapter)
{ {
return i2c_detect(adapter, &addr_data, &atxp1_detect); return i2c_probe(adapter, &addr_data, &atxp1_detect);
}; };
static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
...@@ -295,7 +296,7 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -295,7 +296,7 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
} }
/* Get VRM */ /* Get VRM */
data->vrm = i2c_which_vrm(); data->vrm = vid_which_vrm();
if ((data->vrm != 90) && (data->vrm != 91)) { if ((data->vrm != 90) && (data->vrm != 91)) {
dev_err(&new_client->dev, "Not supporting VRM %d.%d\n", dev_err(&new_client->dev, "Not supporting VRM %d.%d\n",
...@@ -317,6 +318,12 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -317,6 +318,12 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit_free; goto exit_free;
} }
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_gpio1); device_create_file(&new_client->dev, &dev_attr_gpio1);
device_create_file(&new_client->dev, &dev_attr_gpio2); device_create_file(&new_client->dev, &dev_attr_gpio2);
device_create_file(&new_client->dev, &dev_attr_cpu0_vid); device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
...@@ -326,6 +333,8 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -326,6 +333,8 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -334,14 +343,17 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -334,14 +343,17 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
static int atxp1_detach_client(struct i2c_client * client) static int atxp1_detach_client(struct i2c_client * client)
{ {
struct atxp1_data * data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
err = i2c_detach_client(client); err = i2c_detach_client(client);
if (err) if (err)
dev_err(&client->dev, "Failed to detach client.\n"); dev_err(&client->dev, "Failed to detach client.\n");
else else
kfree(i2c_get_clientdata(client)); kfree(data);
return err; return err;
}; };
......
...@@ -26,16 +26,16 @@ ...@@ -26,16 +26,16 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
#include "lm75.h" #include "lm75.h"
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_1(ds1621); I2C_CLIENT_INSMOD_1(ds1621);
static int polarity = -1; static int polarity = -1;
module_param(polarity, int, 0); module_param(polarity, int, 0);
MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low"); MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low");
...@@ -71,6 +71,7 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low") ...@@ -71,6 +71,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 i2c_client client;
struct class_device *class_dev;
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 */
...@@ -179,10 +180,10 @@ static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); ...@@ -179,10 +180,10 @@ static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
static int ds1621_attach_adapter(struct i2c_adapter *adapter) static int ds1621_attach_adapter(struct i2c_adapter *adapter)
{ {
return i2c_detect(adapter, &addr_data, ds1621_detect); return i2c_probe(adapter, &addr_data, ds1621_detect);
} }
/* This function is called by i2c_detect */ /* This function is called by i2c_probe */
int ds1621_detect(struct i2c_adapter *adapter, int address, int ds1621_detect(struct i2c_adapter *adapter, int address,
int kind) int kind)
{ {
...@@ -250,6 +251,12 @@ int ds1621_detect(struct i2c_adapter *adapter, int address, ...@@ -250,6 +251,12 @@ int ds1621_detect(struct i2c_adapter *adapter, int address,
ds1621_init_client(new_client); ds1621_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_alarms); device_create_file(&new_client->dev, &dev_attr_alarms);
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp1_min); device_create_file(&new_client->dev, &dev_attr_temp1_min);
...@@ -259,6 +266,8 @@ int ds1621_detect(struct i2c_adapter *adapter, int address, ...@@ -259,6 +266,8 @@ 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_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -267,15 +276,15 @@ int ds1621_detect(struct i2c_adapter *adapter, int address, ...@@ -267,15 +276,15 @@ int ds1621_detect(struct i2c_adapter *adapter, int address,
static int ds1621_detach_client(struct i2c_client *client) static int ds1621_detach_client(struct i2c_client *client)
{ {
struct ds1621_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -31,20 +31,20 @@ ...@@ -31,20 +31,20 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
*/ */
static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* /*
* Insmod parameters * Insmod parameters
*/ */
SENSORS_INSMOD_1(fscher); I2C_CLIENT_INSMOD_1(fscher);
/* /*
* The FSCHER registers * The FSCHER registers
...@@ -132,6 +132,7 @@ static struct i2c_driver fscher_driver = { ...@@ -132,6 +132,7 @@ static struct i2c_driver fscher_driver = {
struct fscher_data { struct fscher_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
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 */
...@@ -287,7 +288,7 @@ static int fscher_attach_adapter(struct i2c_adapter *adapter) ...@@ -287,7 +288,7 @@ static int fscher_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, fscher_detect); return i2c_probe(adapter, &addr_data, fscher_detect);
} }
static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
...@@ -341,6 +342,12 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -341,6 +342,12 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
fscher_init_client(new_client); fscher_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file_revision(new_client); device_create_file_revision(new_client);
device_create_file_alarms(new_client); device_create_file_alarms(new_client);
device_create_file_control(new_client); device_create_file_control(new_client);
...@@ -360,6 +367,8 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -360,6 +367,8 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -368,15 +377,15 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -368,15 +377,15 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
static int fscher_detach_client(struct i2c_client *client) static int fscher_detach_client(struct i2c_client *client)
{ {
struct fscher_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -34,19 +34,19 @@ ...@@ -34,19 +34,19 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
*/ */
static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* /*
* Insmod parameters * Insmod parameters
*/ */
SENSORS_INSMOD_1(fscpos); I2C_CLIENT_INSMOD_1(fscpos);
/* /*
* The FSCPOS registers * The FSCPOS registers
...@@ -113,6 +113,7 @@ static struct i2c_driver fscpos_driver = { ...@@ -113,6 +113,7 @@ static struct i2c_driver fscpos_driver = {
*/ */
struct fscpos_data { struct fscpos_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* 0 until following fields are valid */ char valid; /* 0 until following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -434,7 +435,7 @@ static int fscpos_attach_adapter(struct i2c_adapter *adapter) ...@@ -434,7 +435,7 @@ static int fscpos_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, fscpos_detect); return i2c_probe(adapter, &addr_data, fscpos_detect);
} }
int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
...@@ -496,6 +497,12 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -496,6 +497,12 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision); dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_event); device_create_file(&new_client->dev, &dev_attr_event);
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_in1_input); device_create_file(&new_client->dev, &dev_attr_in1_input);
...@@ -526,6 +533,8 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -526,6 +533,8 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -534,14 +543,14 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -534,14 +543,14 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
static int fscpos_detach_client(struct i2c_client *client) static int fscpos_detach_client(struct i2c_client *client)
{ {
struct fscpos_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, client"
" not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
} kfree(data);
kfree(i2c_get_clientdata(client));
return 0; return 0;
} }
......
...@@ -41,14 +41,14 @@ ...@@ -41,14 +41,14 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_2(gl518sm_r00, gl518sm_r80); I2C_CLIENT_INSMOD_2(gl518sm_r00, gl518sm_r80);
/* Many GL518 constants specified below */ /* Many GL518 constants specified below */
...@@ -117,6 +117,7 @@ static inline u8 FAN_TO_REG(long rpm, int div) ...@@ -117,6 +117,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; struct i2c_client client;
struct class_device *class_dev;
enum chips type; enum chips type;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -346,7 +347,7 @@ static int gl518_attach_adapter(struct i2c_adapter *adapter) ...@@ -346,7 +347,7 @@ static int gl518_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, gl518_detect); return i2c_probe(adapter, &addr_data, gl518_detect);
} }
static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
...@@ -419,6 +420,12 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -419,6 +420,12 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
gl518_init_client((struct i2c_client *) new_client); gl518_init_client((struct i2c_client *) new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
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_in1_input); device_create_file(&new_client->dev, &dev_attr_in1_input);
device_create_file(&new_client->dev, &dev_attr_in2_input); device_create_file(&new_client->dev, &dev_attr_in2_input);
...@@ -450,6 +457,8 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -450,6 +457,8 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
/* 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_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -477,16 +486,15 @@ static void gl518_init_client(struct i2c_client *client) ...@@ -477,16 +486,15 @@ static void gl518_init_client(struct i2c_client *client)
static int gl518_detach_client(struct i2c_client *client) static int gl518_detach_client(struct i2c_client *client)
{ {
struct gl518_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n");
return err;
}
kfree(i2c_get_clientdata(client)); if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0; return 0;
} }
......
...@@ -26,8 +26,9 @@ ...@@ -26,8 +26,9 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/i2c-vid.h> #include <linux/hwmon-vid.h>
#include <linux/err.h>
/* Type of the extra sensor */ /* Type of the extra sensor */
static unsigned short extra_sensor_type; static unsigned short extra_sensor_type;
...@@ -36,10 +37,9 @@ MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=tempe ...@@ -36,10 +37,9 @@ MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=tempe
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_1(gl520sm); I2C_CLIENT_INSMOD_1(gl520sm);
/* Many GL520 constants specified below /* Many GL520 constants specified below
One of the inputs can be configured as either temp or voltage. One of the inputs can be configured as either temp or voltage.
...@@ -120,6 +120,7 @@ static struct i2c_driver gl520_driver = { ...@@ -120,6 +120,7 @@ static struct i2c_driver gl520_driver = {
/* Client data */ /* Client data */
struct gl520_data { struct gl520_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until the following fields are valid */ char valid; /* zero until the following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -518,7 +519,7 @@ static int gl520_attach_adapter(struct i2c_adapter *adapter) ...@@ -518,7 +519,7 @@ static int gl520_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, gl520_detect); return i2c_probe(adapter, &addr_data, gl520_detect);
} }
static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
...@@ -571,6 +572,12 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -571,6 +572,12 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
gl520_init_client(new_client); gl520_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file_vid(new_client, 0); device_create_file_vid(new_client, 0);
device_create_file_in(new_client, 0); device_create_file_in(new_client, 0);
...@@ -592,6 +599,8 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -592,6 +599,8 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -608,7 +617,7 @@ static void gl520_init_client(struct i2c_client *client) ...@@ -608,7 +617,7 @@ static void gl520_init_client(struct i2c_client *client)
conf = oldconf = gl520_read_value(client, GL520_REG_CONF); conf = oldconf = gl520_read_value(client, GL520_REG_CONF);
data->alarm_mask = 0xff; data->alarm_mask = 0xff;
data->vrm = i2c_which_vrm(); data->vrm = vid_which_vrm();
if (extra_sensor_type == 1) if (extra_sensor_type == 1)
conf &= ~0x10; conf &= ~0x10;
...@@ -639,15 +648,15 @@ static void gl520_init_client(struct i2c_client *client) ...@@ -639,15 +648,15 @@ static void gl520_init_client(struct i2c_client *client)
static int gl520_detach_client(struct i2c_client *client) static int gl520_detach_client(struct i2c_client *client)
{ {
struct gl520_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
/* /*
i2c-sensor-vid.c - Part of lm_sensors, Linux kernel modules for hardware hwmon-vid.c - VID/VRM/VRD voltage conversions
monitoring
Copyright (c) 2004 Rudolf Marek <r.marek@sh.cvut.cz> Copyright (c) 2004 Rudolf Marek <r.marek@sh.cvut.cz>
Partly imported from i2c-vid.h of the lm_sensors project
Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
With assistance from Trent Piepho <xyzzy@speakeasy.org>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
...@@ -22,6 +25,84 @@ ...@@ -22,6 +25,84 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/hwmon-vid.h>
/*
Common code for decoding VID pins.
References:
For VRM 8.4 to 9.1, "VRM x.y DC-DC Converter Design Guidelines",
available at http://developer.intel.com/.
For VRD 10.0 and up, "VRD x.y Design Guide",
available at http://developer.intel.com/.
AMD Opteron processors don't follow the Intel specifications.
I'm going to "make up" 2.4 as the spec number for the Opterons.
No good reason just a mnemonic for the 24x Opteron processor
series.
Opteron VID encoding is:
00000 = 1.550 V
00001 = 1.525 V
. . . .
11110 = 0.800 V
11111 = 0.000 V (off)
*/
/* vrm is the VRM/VRD document version multiplied by 10.
val is the 4-, 5- or 6-bit VID code.
Returned value is in mV to avoid floating point in the kernel. */
int vid_from_reg(int val, int vrm)
{
int vid;
switch(vrm) {
case 0:
return 0;
case 100: /* VRD 10.0 */
if((val & 0x1f) == 0x1f)
return 0;
if((val & 0x1f) <= 0x09 || val == 0x0a)
vid = 10875 - (val & 0x1f) * 250;
else
vid = 18625 - (val & 0x1f) * 250;
if(val & 0x20)
vid -= 125;
vid /= 10; /* only return 3 dec. places for now */
return vid;
case 24: /* Opteron processor */
return(val == 0x1f ? 0 : 1550 - val * 25);
case 91: /* VRM 9.1 */
case 90: /* VRM 9.0 */
return(val == 0x1f ? 0 :
1850 - val * 25);
case 85: /* VRM 8.5 */
return((val & 0x10 ? 25 : 0) +
((val & 0x0f) > 0x04 ? 2050 : 1250) -
((val & 0x0f) * 50));
case 84: /* VRM 8.4 */
val &= 0x0f;
/* fall through */
default: /* VRM 8.2 */
return(val == 0x1f ? 0 :
val & 0x10 ? 5100 - (val) * 100 :
2050 - (val) * 50);
}
}
/*
After this point is the code to automatically determine which
VRM/VRD specification should be used depending on the CPU.
*/
struct vrm_model { struct vrm_model {
u8 vendor; u8 vendor;
...@@ -38,14 +119,17 @@ static struct vrm_model vrm_models[] = { ...@@ -38,14 +119,17 @@ static struct vrm_model vrm_models[] = {
{X86_VENDOR_AMD, 0x6, ANY, 90}, /* Athlon Duron etc */ {X86_VENDOR_AMD, 0x6, ANY, 90}, /* Athlon Duron etc */
{X86_VENDOR_AMD, 0xF, ANY, 24}, /* Athlon 64, Opteron */ {X86_VENDOR_AMD, 0xF, ANY, 24}, /* Athlon 64, Opteron */
{X86_VENDOR_INTEL, 0x6, 0x9, 85}, /* 0.13um too */ {X86_VENDOR_INTEL, 0x6, 0x9, 85}, /* 0.13um too */
{X86_VENDOR_INTEL, 0x6, 0xB, 85}, /* 0xB Tualatin */ {X86_VENDOR_INTEL, 0x6, 0xB, 85}, /* Tualatin */
{X86_VENDOR_INTEL, 0x6, ANY, 82}, /* any P6 */ {X86_VENDOR_INTEL, 0x6, ANY, 82}, /* any P6 */
{X86_VENDOR_INTEL, 0x7, ANY, 0}, /* Itanium */ {X86_VENDOR_INTEL, 0x7, ANY, 0}, /* Itanium */
{X86_VENDOR_INTEL, 0xF, 0x0, 90}, /* P4 */
{X86_VENDOR_INTEL, 0xF, 0x1, 90}, /* P4 Willamette */
{X86_VENDOR_INTEL, 0xF, 0x2, 90}, /* P4 Northwood */
{X86_VENDOR_INTEL, 0xF, 0x3, 100}, /* P4 Prescott */ {X86_VENDOR_INTEL, 0xF, 0x3, 100}, /* P4 Prescott */
{X86_VENDOR_INTEL, 0xF, ANY, 90}, /* P4 before Prescott */ {X86_VENDOR_INTEL, 0xF, 0x4, 100}, /* P4 Prescott */
{X86_VENDOR_INTEL, 0x10,ANY, 0}, /* Itanium 2 */ {X86_VENDOR_INTEL, 0x10,ANY, 0}, /* Itanium 2 */
{X86_VENDOR_UNKNOWN, ANY, ANY, 0} /* stop here */ {X86_VENDOR_UNKNOWN, ANY, ANY, 0} /* stop here */
}; };
static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor) static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor)
{ {
...@@ -53,9 +137,9 @@ static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor) ...@@ -53,9 +137,9 @@ static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor)
while (vrm_models[i].vendor!=X86_VENDOR_UNKNOWN) { while (vrm_models[i].vendor!=X86_VENDOR_UNKNOWN) {
if (vrm_models[i].vendor==vendor) if (vrm_models[i].vendor==vendor)
if ((vrm_models[i].eff_family==eff_family)&& \ if ((vrm_models[i].eff_family==eff_family)
((vrm_models[i].eff_model==eff_model)|| \ && ((vrm_models[i].eff_model==eff_model) ||
(vrm_models[i].eff_model==ANY))) (vrm_models[i].eff_model==ANY)))
return vrm_models[i].vrm_type; return vrm_models[i].vrm_type;
i++; i++;
} }
...@@ -63,15 +147,16 @@ static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor) ...@@ -63,15 +147,16 @@ static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor)
return 0; return 0;
} }
int i2c_which_vrm(void) int vid_which_vrm(void)
{ {
struct cpuinfo_x86 *c = cpu_data; struct cpuinfo_x86 *c = cpu_data;
u32 eax; u32 eax;
u8 eff_family, eff_model; u8 eff_family, eff_model;
int vrm_ret; int vrm_ret;
if (c->x86 < 6) return 0; /* any CPU with familly lower than 6 if (c->x86 < 6) /* Any CPU with family lower than 6 */
dont have VID and/or CPUID */ return 0; /* doesn't have VID and/or CPUID */
eax = cpuid_eax(1); eax = cpuid_eax(1);
eff_family = ((eax & 0x00000F00)>>8); eff_family = ((eax & 0x00000F00)>>8);
eff_model = ((eax & 0x000000F0)>>4); eff_model = ((eax & 0x000000F0)>>4);
...@@ -81,18 +166,24 @@ int i2c_which_vrm(void) ...@@ -81,18 +166,24 @@ int i2c_which_vrm(void)
} }
vrm_ret = find_vrm(eff_family,eff_model,c->x86_vendor); vrm_ret = find_vrm(eff_family,eff_model,c->x86_vendor);
if (vrm_ret == 0) if (vrm_ret == 0)
printk(KERN_INFO "i2c-sensor.o: Unknown VRM version of your" printk(KERN_INFO "hwmon-vid: Unknown VRM version of your "
" x86 CPU\n"); "x86 CPU\n");
return vrm_ret; return vrm_ret;
} }
/* and now for something completely different for Non-x86 world*/ /* and now something completely different for the non-x86 world */
#else #else
int i2c_which_vrm(void) int vid_which_vrm(void)
{ {
printk(KERN_INFO "i2c-sensor.o: Unknown VRM version of your CPU\n"); printk(KERN_INFO "hwmon-vid: Unknown VRM version of your CPU\n");
return 0; return 0;
} }
#endif #endif
EXPORT_SYMBOL(i2c_which_vrm); EXPORT_SYMBOL(vid_from_reg);
EXPORT_SYMBOL(vid_which_vrm);
MODULE_AUTHOR("Rudolf Marek <r.marek@sh.cvut.cz>");
MODULE_DESCRIPTION("hwmon-vid driver");
MODULE_LICENSE("GPL");
/*
hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring
This file defines the sysfs class "hwmon", for use by sensors drivers.
Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com>
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; version 2 of the License.
*/
#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/kdev_t.h>
#include <linux/idr.h>
#include <linux/hwmon.h>
#define HWMON_ID_PREFIX "hwmon"
#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d"
static struct class *hwmon_class;
static DEFINE_IDR(hwmon_idr);
/**
* hwmon_device_register - register w/ hwmon sysfs class
* @dev: the device to register
*
* hwmon_device_unregister() must be called when the class device is no
* longer needed.
*
* Returns the pointer to the new struct class device.
*/
struct class_device *hwmon_device_register(struct device *dev)
{
struct class_device *cdev;
int id;
if (idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0)
return ERR_PTR(-ENOMEM);
if (idr_get_new(&hwmon_idr, NULL, &id) < 0)
return ERR_PTR(-ENOMEM);
id = id & MAX_ID_MASK;
cdev = class_device_create(hwmon_class, MKDEV(0,0), dev,
HWMON_ID_FORMAT, id);
if (IS_ERR(cdev))
idr_remove(&hwmon_idr, id);
return cdev;
}
/**
* hwmon_device_unregister - removes the previously registered class device
*
* @cdev: the class device to destroy
*/
void hwmon_device_unregister(struct class_device *cdev)
{
int id;
if (sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1) {
class_device_unregister(cdev);
idr_remove(&hwmon_idr, id);
} else
dev_dbg(cdev->dev,
"hwmon_device_unregister() failed: bad class ID!\n");
}
static int __init hwmon_init(void)
{
hwmon_class = class_create(THIS_MODULE, "hwmon");
if (IS_ERR(hwmon_class)) {
printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n");
return PTR_ERR(hwmon_class);
}
return 0;
}
static void __exit hwmon_exit(void)
{
class_destroy(hwmon_class);
}
module_init(hwmon_init);
module_exit(hwmon_exit);
EXPORT_SYMBOL_GPL(hwmon_device_register);
EXPORT_SYMBOL_GPL(hwmon_device_unregister);
MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
MODULE_DESCRIPTION("hardware monitoring sysfs/class support");
MODULE_LICENSE("GPL");
...@@ -36,19 +36,21 @@ ...@@ -36,19 +36,21 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-isa.h>
#include <linux/i2c-vid.h> #include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <asm/io.h> #include <asm/io.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
0x2e, 0x2f, I2C_CLIENT_END }; 0x2e, 0x2f, I2C_CLIENT_END };
static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END }; static unsigned short isa_address = 0x290;
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_2(it87, it8712); I2C_CLIENT_INSMOD_2(it87, it8712);
#define REG 0x2e /* The register to read/write */ #define REG 0x2e /* The register to read/write */
#define DEV 0x07 /* Register: Logical device select */ #define DEV 0x07 /* Register: Logical device select */
...@@ -192,6 +194,7 @@ static int DIV_TO_REG(int val) ...@@ -192,6 +194,7 @@ static int DIV_TO_REG(int val)
allocated. */ allocated. */
struct it87_data { struct it87_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -218,7 +221,7 @@ struct it87_data { ...@@ -218,7 +221,7 @@ struct it87_data {
static int it87_attach_adapter(struct i2c_adapter *adapter); static int it87_attach_adapter(struct i2c_adapter *adapter);
static int it87_find(int *address); static int it87_isa_attach_adapter(struct i2c_adapter *adapter);
static int it87_detect(struct i2c_adapter *adapter, int address, int kind); static int it87_detect(struct i2c_adapter *adapter, int address, int kind);
static int it87_detach_client(struct i2c_client *client); static int it87_detach_client(struct i2c_client *client);
...@@ -239,6 +242,14 @@ static struct i2c_driver it87_driver = { ...@@ -239,6 +242,14 @@ static struct i2c_driver it87_driver = {
.detach_client = it87_detach_client, .detach_client = it87_detach_client,
}; };
static struct i2c_driver it87_isa_driver = {
.owner = THIS_MODULE,
.name = "it87-isa",
.attach_adapter = it87_isa_attach_adapter,
.detach_client = it87_detach_client,
};
static ssize_t show_in(struct device *dev, struct device_attribute *attr, static ssize_t show_in(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -686,11 +697,16 @@ static int it87_attach_adapter(struct i2c_adapter *adapter) ...@@ -686,11 +697,16 @@ static int it87_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, it87_detect); return i2c_probe(adapter, &addr_data, it87_detect);
} }
/* SuperIO detection - will change normal_isa[0] if a chip is found */ static int it87_isa_attach_adapter(struct i2c_adapter *adapter)
static int it87_find(int *address) {
return it87_detect(adapter, isa_address, -1);
}
/* SuperIO detection - will change isa_address if a chip is found */
static int __init it87_find(int *address)
{ {
int err = -ENODEV; int err = -ENODEV;
...@@ -721,7 +737,7 @@ static int it87_find(int *address) ...@@ -721,7 +737,7 @@ static int it87_find(int *address)
return err; return err;
} }
/* This function is called by i2c_detect */ /* This function is called by i2c_probe */
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;
...@@ -738,7 +754,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -738,7 +754,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
/* Reserve the ISA region */ /* Reserve the ISA region */
if (is_isa) if (is_isa)
if (!request_region(address, IT87_EXTENT, it87_driver.name)) if (!request_region(address, IT87_EXTENT, it87_isa_driver.name))
goto ERROR0; goto ERROR0;
/* Probe whether there is anything available on this address. Already /* Probe whether there is anything available on this address. Already
...@@ -784,7 +800,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -784,7 +800,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
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;
new_client->driver = &it87_driver; new_client->driver = is_isa ? &it87_isa_driver : &it87_driver;
new_client->flags = 0; new_client->flags = 0;
/* Now, we do the remaining detection. */ /* Now, we do the remaining detection. */
...@@ -840,6 +856,12 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -840,6 +856,12 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
it87_init_client(new_client, data); it87_init_client(new_client, data);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR3;
}
device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr);
...@@ -897,13 +919,15 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -897,13 +919,15 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
} }
if (data->type == it8712) { if (data->type == it8712) {
data->vrm = i2c_which_vrm(); data->vrm = vid_which_vrm();
device_create_file_vrm(new_client); device_create_file_vrm(new_client);
device_create_file_vid(new_client); device_create_file_vid(new_client);
} }
return 0; return 0;
ERROR3:
i2c_detach_client(new_client);
ERROR2: ERROR2:
kfree(data); kfree(data);
ERROR1: ERROR1:
...@@ -915,17 +939,17 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -915,17 +939,17 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
static int it87_detach_client(struct i2c_client *client) static int it87_detach_client(struct i2c_client *client)
{ {
struct it87_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev,
"Client deregistration failed, client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
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(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
...@@ -1158,16 +1182,28 @@ static struct it87_data *it87_update_device(struct device *dev) ...@@ -1158,16 +1182,28 @@ static struct it87_data *it87_update_device(struct device *dev)
static int __init sm_it87_init(void) static int __init sm_it87_init(void)
{ {
int addr; int addr, res;
if (!it87_find(&addr)) { if (!it87_find(&addr)) {
normal_isa[0] = addr; isa_address = addr;
}
res = i2c_add_driver(&it87_driver);
if (res)
return res;
res = i2c_isa_add_driver(&it87_isa_driver);
if (res) {
i2c_del_driver(&it87_driver);
return res;
} }
return i2c_add_driver(&it87_driver);
return 0;
} }
static void __exit sm_it87_exit(void) static void __exit sm_it87_exit(void)
{ {
i2c_isa_del_driver(&it87_isa_driver);
i2c_del_driver(&it87_driver); i2c_del_driver(&it87_driver);
} }
......
...@@ -42,8 +42,9 @@ ...@@ -42,8 +42,9 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -51,13 +52,12 @@ ...@@ -51,13 +52,12 @@
*/ */
static unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* /*
* Insmod parameters * Insmod parameters
*/ */
SENSORS_INSMOD_1(lm63); I2C_CLIENT_INSMOD_1(lm63);
/* /*
* The LM63 registers * The LM63 registers
...@@ -152,6 +152,7 @@ static struct i2c_driver lm63_driver = { ...@@ -152,6 +152,7 @@ static struct i2c_driver lm63_driver = {
struct lm63_data { struct lm63_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
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 */
...@@ -358,7 +359,7 @@ static int lm63_attach_adapter(struct i2c_adapter *adapter) ...@@ -358,7 +359,7 @@ static int lm63_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, lm63_detect); return i2c_probe(adapter, &addr_data, lm63_detect);
} }
/* /*
...@@ -437,6 +438,12 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -437,6 +438,12 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
lm63_init_client(new_client); lm63_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
if (data->config & 0x04) { /* tachometer enabled */ if (data->config & 0x04) { /* tachometer enabled */
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_fan1_input.dev_attr); &sensor_dev_attr_fan1_input.dev_attr);
...@@ -462,6 +469,8 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -462,6 +469,8 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -505,15 +514,15 @@ static void lm63_init_client(struct i2c_client *client) ...@@ -505,15 +514,15 @@ static void lm63_init_client(struct i2c_client *client)
static int lm63_detach_client(struct i2c_client *client) static int lm63_detach_client(struct i2c_client *client)
{ {
struct lm63_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -23,17 +23,17 @@ ...@@ -23,17 +23,17 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
#include "lm75.h" #include "lm75.h"
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_1(lm75); I2C_CLIENT_INSMOD_1(lm75);
/* Many LM75 constants specified below */ /* Many LM75 constants specified below */
...@@ -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 i2c_client client;
struct class_device *class_dev;
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 */
...@@ -107,10 +108,10 @@ static int lm75_attach_adapter(struct i2c_adapter *adapter) ...@@ -107,10 +108,10 @@ static int lm75_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, lm75_detect); return i2c_probe(adapter, &addr_data, lm75_detect);
} }
/* This function is called by i2c_detect */ /* This function is called by i2c_probe */
static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
{ {
int i; int i;
...@@ -119,16 +120,6 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -119,16 +120,6 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
int err = 0; int err = 0;
const char *name = ""; const char *name = "";
/* Make sure we aren't probing the ISA bus!! This is just a safety check
at this moment; i2c_detect really won't call us. */
#ifdef DEBUG
if (i2c_is_isa_adapter(adapter)) {
dev_dbg(&adapter->dev,
"lm75_detect called for an ISA bus adapter?!?\n");
goto exit;
}
#endif
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA)) I2C_FUNC_SMBUS_WORD_DATA))
goto exit; goto exit;
...@@ -208,12 +199,20 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -208,12 +199,20 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
lm75_init_client(new_client); lm75_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_temp1_max); device_create_file(&new_client->dev, &dev_attr_temp1_max);
device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -222,8 +221,10 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -222,8 +221,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)
{ {
struct lm75_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->class_dev);
i2c_detach_client(client); i2c_detach_client(client);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
...@@ -251,8 +252,12 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) ...@@ -251,8 +252,12 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
static void lm75_init_client(struct i2c_client *client) static void lm75_init_client(struct i2c_client *client)
{ {
/* Initialize the LM75 chip */ int reg;
lm75_write_value(client, LM75_REG_CONF, 0);
/* Enable if in shutdown mode */
reg = lm75_read_value(client, LM75_REG_CONF);
if (reg >= 0 && (reg & 0x01))
lm75_write_value(client, LM75_REG_CONF, reg & 0xfe);
} }
static struct lm75_data *lm75_update_device(struct device *dev) static struct lm75_data *lm75_update_device(struct device *dev)
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
which contains this code, we don't worry about the wasted space. which contains this code, we don't worry about the wasted space.
*/ */
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
/* straight from the datasheet */ /* straight from the datasheet */
#define LM75_TEMP_MIN (-55000) #define LM75_TEMP_MIN (-55000)
......
...@@ -30,15 +30,14 @@ ...@@ -30,15 +30,14 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_1(lm77); I2C_CLIENT_INSMOD_1(lm77);
/* The LM77 registers */ /* The LM77 registers */
#define LM77_REG_TEMP 0x00 #define LM77_REG_TEMP 0x00
...@@ -51,6 +50,7 @@ SENSORS_INSMOD_1(lm77); ...@@ -51,6 +50,7 @@ SENSORS_INSMOD_1(lm77);
/* Each client has this additional data */ /* Each client has this additional data */
struct lm77_data { struct lm77_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; char valid;
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -208,10 +208,10 @@ static int lm77_attach_adapter(struct i2c_adapter *adapter) ...@@ -208,10 +208,10 @@ static int lm77_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, lm77_detect); return i2c_probe(adapter, &addr_data, lm77_detect);
} }
/* This function is called by i2c_detect */ /* This function is called by i2c_probe */
static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
{ {
struct i2c_client *new_client; struct i2c_client *new_client;
...@@ -317,6 +317,12 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -317,6 +317,12 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
lm77_init_client(new_client); lm77_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp1_crit); device_create_file(&new_client->dev, &dev_attr_temp1_crit);
device_create_file(&new_client->dev, &dev_attr_temp1_min); device_create_file(&new_client->dev, &dev_attr_temp1_min);
...@@ -327,6 +333,8 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -327,6 +333,8 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_alarms); device_create_file(&new_client->dev, &dev_attr_alarms);
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -335,8 +343,10 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -335,8 +343,10 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
static int lm77_detach_client(struct i2c_client *client) static int lm77_detach_client(struct i2c_client *client)
{ {
struct lm77_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->class_dev);
i2c_detach_client(client); i2c_detach_client(client);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -23,7 +23,10 @@ ...@@ -23,7 +23,10 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-isa.h>
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <asm/io.h> #include <asm/io.h>
/* Addresses to scan */ /* Addresses to scan */
...@@ -31,10 +34,10 @@ static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, ...@@ -31,10 +34,10 @@ static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24,
0x25, 0x26, 0x27, 0x28, 0x29, 0x25, 0x26, 0x27, 0x28, 0x29,
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
0x2f, I2C_CLIENT_END }; 0x2f, I2C_CLIENT_END };
static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END }; static unsigned short isa_address = 0x290;
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_3(lm78, lm78j, lm79); I2C_CLIENT_INSMOD_2(lm78, lm79);
/* Many LM78 constants specified below */ /* Many LM78 constants specified below */
...@@ -104,13 +107,6 @@ static inline int TEMP_FROM_REG(s8 val) ...@@ -104,13 +107,6 @@ static inline int TEMP_FROM_REG(s8 val)
return val * 1000; return val * 1000;
} }
/* VID: mV
REG: (see doc/vid) */
static inline int VID_FROM_REG(u8 val)
{
return val==0x1f ? 0 : val>=0x10 ? 5100-val*100 : 2050-val*50;
}
#define DIV_FROM_REG(val) (1 << (val)) #define DIV_FROM_REG(val) (1 << (val))
/* There are some complications in a module like this. First off, LM78 chips /* There are some complications in a module like this. First off, LM78 chips
...@@ -134,6 +130,7 @@ static inline int VID_FROM_REG(u8 val) ...@@ -134,6 +130,7 @@ static inline int VID_FROM_REG(u8 val)
allocated. */ allocated. */
struct lm78_data { struct lm78_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -156,6 +153,7 @@ struct lm78_data { ...@@ -156,6 +153,7 @@ struct lm78_data {
static int lm78_attach_adapter(struct i2c_adapter *adapter); static int lm78_attach_adapter(struct i2c_adapter *adapter);
static int lm78_isa_attach_adapter(struct i2c_adapter *adapter);
static int lm78_detect(struct i2c_adapter *adapter, int address, int kind); static int lm78_detect(struct i2c_adapter *adapter, int address, int kind);
static int lm78_detach_client(struct i2c_client *client); static int lm78_detach_client(struct i2c_client *client);
...@@ -174,6 +172,14 @@ static struct i2c_driver lm78_driver = { ...@@ -174,6 +172,14 @@ static struct i2c_driver lm78_driver = {
.detach_client = lm78_detach_client, .detach_client = lm78_detach_client,
}; };
static struct i2c_driver lm78_isa_driver = {
.owner = THIS_MODULE,
.name = "lm78-isa",
.attach_adapter = lm78_isa_attach_adapter,
.detach_client = lm78_detach_client,
};
/* 7 Voltages */ /* 7 Voltages */
static ssize_t show_in(struct device *dev, char *buf, int nr) static ssize_t show_in(struct device *dev, char *buf, int nr)
{ {
...@@ -445,7 +451,7 @@ static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL); ...@@ -445,7 +451,7 @@ static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL);
static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
{ {
struct lm78_data *data = lm78_update_device(dev); struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%d\n", VID_FROM_REG(data->vid)); return sprintf(buf, "%d\n", vid_from_reg(82, data->vid));
} }
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
...@@ -465,10 +471,15 @@ static int lm78_attach_adapter(struct i2c_adapter *adapter) ...@@ -465,10 +471,15 @@ static int lm78_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, lm78_detect); return i2c_probe(adapter, &addr_data, lm78_detect);
}
static int lm78_isa_attach_adapter(struct i2c_adapter *adapter)
{
return lm78_detect(adapter, isa_address, -1);
} }
/* This function is called by i2c_detect */ /* This function is called by i2c_probe */
int lm78_detect(struct i2c_adapter *adapter, int address, int kind) int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
{ {
int i, err; int i, err;
...@@ -485,7 +496,8 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -485,7 +496,8 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
/* Reserve the ISA region */ /* Reserve the ISA region */
if (is_isa) if (is_isa)
if (!request_region(address, LM78_EXTENT, lm78_driver.name)) { if (!request_region(address, LM78_EXTENT,
lm78_isa_driver.name)) {
err = -EBUSY; err = -EBUSY;
goto ERROR0; goto ERROR0;
} }
...@@ -540,7 +552,7 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -540,7 +552,7 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
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;
new_client->driver = &lm78_driver; new_client->driver = is_isa ? &lm78_isa_driver : &lm78_driver;
new_client->flags = 0; new_client->flags = 0;
/* Now, we do the remaining detection. */ /* Now, we do the remaining detection. */
...@@ -559,10 +571,9 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -559,10 +571,9 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
/* Determine the chip type. */ /* Determine the chip type. */
if (kind <= 0) { if (kind <= 0) {
i = lm78_read_value(new_client, LM78_REG_CHIPID); i = lm78_read_value(new_client, LM78_REG_CHIPID);
if (i == 0x00 || i == 0x20) if (i == 0x00 || i == 0x20 /* LM78 */
|| i == 0x40) /* LM78-J */
kind = lm78; kind = lm78;
else if (i == 0x40)
kind = lm78j;
else if ((i & 0xfe) == 0xc0) else if ((i & 0xfe) == 0xc0)
kind = lm79; kind = lm79;
else { else {
...@@ -578,8 +589,6 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -578,8 +589,6 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind == lm78) { if (kind == lm78) {
client_name = "lm78"; client_name = "lm78";
} else if (kind == lm78j) {
client_name = "lm78-j";
} else if (kind == lm79) { } else if (kind == lm79) {
client_name = "lm79"; client_name = "lm79";
} }
...@@ -605,6 +614,12 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -605,6 +614,12 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
} }
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR3;
}
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);
device_create_file(&new_client->dev, &dev_attr_in0_max); device_create_file(&new_client->dev, &dev_attr_in0_max);
...@@ -643,6 +658,8 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -643,6 +658,8 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR3:
i2c_detach_client(new_client);
ERROR2: ERROR2:
kfree(data); kfree(data);
ERROR1: ERROR1:
...@@ -654,18 +671,18 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -654,18 +671,18 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
static int lm78_detach_client(struct i2c_client *client) static int lm78_detach_client(struct i2c_client *client)
{ {
struct lm78_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev,
"Client deregistration failed, client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
if(i2c_is_isa_client(client)) if(i2c_is_isa_client(client))
release_region(client->addr, LM78_EXTENT); release_region(client->addr, LM78_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
...@@ -777,18 +794,31 @@ static struct lm78_data *lm78_update_device(struct device *dev) ...@@ -777,18 +794,31 @@ static struct lm78_data *lm78_update_device(struct device *dev)
static int __init sm_lm78_init(void) static int __init sm_lm78_init(void)
{ {
return i2c_add_driver(&lm78_driver); int res;
res = i2c_add_driver(&lm78_driver);
if (res)
return res;
res = i2c_isa_add_driver(&lm78_isa_driver);
if (res) {
i2c_del_driver(&lm78_driver);
return res;
}
return 0;
} }
static void __exit sm_lm78_exit(void) static void __exit sm_lm78_exit(void)
{ {
i2c_isa_del_driver(&lm78_isa_driver);
i2c_del_driver(&lm78_driver); i2c_del_driver(&lm78_driver);
} }
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
MODULE_DESCRIPTION("LM78, LM78-J and LM79 driver"); MODULE_DESCRIPTION("LM78/LM79 driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
module_init(sm_lm78_init); module_init(sm_lm78_init);
......
...@@ -26,15 +26,15 @@ ...@@ -26,15 +26,15 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c,
0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_1(lm80); I2C_CLIENT_INSMOD_1(lm80);
/* Many LM80 constants specified below */ /* Many LM80 constants specified below */
...@@ -107,6 +107,7 @@ static inline long TEMP_FROM_REG(u16 temp) ...@@ -107,6 +107,7 @@ static inline long TEMP_FROM_REG(u16 temp)
struct lm80_data { struct lm80_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
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 */
...@@ -389,7 +390,7 @@ static int lm80_attach_adapter(struct i2c_adapter *adapter) ...@@ -389,7 +390,7 @@ static int lm80_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, lm80_detect); return i2c_probe(adapter, &addr_data, lm80_detect);
} }
int lm80_detect(struct i2c_adapter *adapter, int address, int kind) int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
...@@ -451,6 +452,12 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -451,6 +452,12 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
data->fan_min[1] = lm80_read_value(new_client, LM80_REG_FAN_MIN(2)); data->fan_min[1] = lm80_read_value(new_client, LM80_REG_FAN_MIN(2));
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto error_detach;
}
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);
device_create_file(&new_client->dev, &dev_attr_in2_min); device_create_file(&new_client->dev, &dev_attr_in2_min);
...@@ -487,6 +494,8 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -487,6 +494,8 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
error_detach:
i2c_detach_client(new_client);
error_free: error_free:
kfree(data); kfree(data);
exit: exit:
...@@ -495,15 +504,15 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -495,15 +504,15 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
static int lm80_detach_client(struct i2c_client *client) static int lm80_detach_client(struct i2c_client *client)
{ {
struct lm80_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -32,8 +32,9 @@ ...@@ -32,8 +32,9 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -45,13 +46,12 @@ static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, ...@@ -45,13 +46,12 @@ static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
0x29, 0x2a, 0x2b, 0x29, 0x2a, 0x2b,
0x4c, 0x4d, 0x4e, 0x4c, 0x4d, 0x4e,
I2C_CLIENT_END }; I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* /*
* Insmod parameters * Insmod parameters
*/ */
SENSORS_INSMOD_1(lm83); I2C_CLIENT_INSMOD_1(lm83);
/* /*
* The LM83 registers * The LM83 registers
...@@ -138,6 +138,7 @@ static struct i2c_driver lm83_driver = { ...@@ -138,6 +138,7 @@ static struct i2c_driver lm83_driver = {
struct lm83_data { struct lm83_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
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 */
...@@ -212,7 +213,7 @@ static int lm83_attach_adapter(struct i2c_adapter *adapter) ...@@ -212,7 +213,7 @@ static int lm83_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, lm83_detect); return i2c_probe(adapter, &addr_data, lm83_detect);
} }
/* /*
...@@ -312,6 +313,12 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -312,6 +313,12 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
*/ */
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_temp1_input.dev_attr); &sensor_dev_attr_temp1_input.dev_attr);
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
...@@ -340,6 +347,8 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -340,6 +347,8 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -348,15 +357,15 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -348,15 +357,15 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
static int lm83_detach_client(struct i2c_client *client) static int lm83_detach_client(struct i2c_client *client)
{ {
struct lm83_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev,
"Client deregistration failed, client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -28,15 +28,15 @@ ...@@ -28,15 +28,15 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/i2c-vid.h> #include <linux/hwmon-vid.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102);
/* The LM85 registers */ /* The LM85 registers */
...@@ -281,15 +281,6 @@ static int ZONE_TO_REG( int zone ) ...@@ -281,15 +281,6 @@ static int ZONE_TO_REG( int zone )
#define PPR_TO_REG(val,fan) (SENSORS_LIMIT((val)-1,0,3)<<(fan *2)) #define PPR_TO_REG(val,fan) (SENSORS_LIMIT((val)-1,0,3)<<(fan *2))
#define PPR_FROM_REG(val,fan) ((((val)>>(fan * 2))&0x03)+1) #define PPR_FROM_REG(val,fan) ((((val)>>(fan * 2))&0x03)+1)
/* i2c-vid.h defines vid_from_reg() */
#define VID_FROM_REG(val,vrm) (vid_from_reg((val),(vrm)))
/* Unlike some other drivers we DO NOT set initial limits. Use
* the config file to set limits. Some users have reported
* motherboards shutting down when we set limits in a previous
* version of the driver.
*/
/* Chip sampling rates /* Chip sampling rates
* *
* Some sensors are not updated more frequently than once per second * Some sensors are not updated more frequently than once per second
...@@ -339,6 +330,7 @@ struct lm85_autofan { ...@@ -339,6 +330,7 @@ struct lm85_autofan {
struct lm85_data { struct lm85_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -1019,7 +1011,7 @@ int lm85_attach_adapter(struct i2c_adapter *adapter) ...@@ -1019,7 +1011,7 @@ int lm85_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, lm85_detect); return i2c_probe(adapter, &addr_data, lm85_detect);
} }
int lm85_detect(struct i2c_adapter *adapter, int address, int lm85_detect(struct i2c_adapter *adapter, int address,
...@@ -1031,11 +1023,6 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -1031,11 +1023,6 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
int err = 0; int err = 0;
const char *type_name = ""; const char *type_name = "";
if (i2c_is_isa_adapter(adapter)) {
/* This chip has no ISA interface */
goto ERROR0 ;
};
if (!i2c_check_functionality(adapter, if (!i2c_check_functionality(adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) { I2C_FUNC_SMBUS_BYTE_DATA)) {
/* We need to be able to do byte I/O */ /* We need to be able to do byte I/O */
...@@ -1160,12 +1147,18 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -1160,12 +1147,18 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
goto ERROR1; goto ERROR1;
/* Set the VRM version */ /* Set the VRM version */
data->vrm = i2c_which_vrm(); data->vrm = vid_which_vrm();
/* Initialize the LM85 chip */ /* Initialize the LM85 chip */
lm85_init_client(new_client); lm85_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR2;
}
device_create_file(&new_client->dev, &dev_attr_fan1_input); device_create_file(&new_client->dev, &dev_attr_fan1_input);
device_create_file(&new_client->dev, &dev_attr_fan2_input); device_create_file(&new_client->dev, &dev_attr_fan2_input);
device_create_file(&new_client->dev, &dev_attr_fan3_input); device_create_file(&new_client->dev, &dev_attr_fan3_input);
...@@ -1235,6 +1228,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -1235,6 +1228,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
return 0; return 0;
/* Error out and cleanup code */ /* Error out and cleanup code */
ERROR2:
i2c_detach_client(new_client);
ERROR1: ERROR1:
kfree(data); kfree(data);
ERROR0: ERROR0:
...@@ -1243,8 +1238,10 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -1243,8 +1238,10 @@ 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)
{ {
struct lm85_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->class_dev);
i2c_detach_client(client); i2c_detach_client(client);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -57,8 +57,9 @@ ...@@ -57,8 +57,9 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/i2c-vid.h> #include <linux/hwmon-vid.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -66,13 +67,12 @@ ...@@ -66,13 +67,12 @@
*/ */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* /*
* Insmod parameters * Insmod parameters
*/ */
SENSORS_INSMOD_1(lm87); I2C_CLIENT_INSMOD_1(lm87);
/* /*
* The LM87 registers * The LM87 registers
...@@ -175,6 +175,7 @@ static struct i2c_driver lm87_driver = { ...@@ -175,6 +175,7 @@ static struct i2c_driver lm87_driver = {
struct lm87_data { struct lm87_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
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 */
...@@ -537,7 +538,7 @@ static int lm87_attach_adapter(struct i2c_adapter *adapter) ...@@ -537,7 +538,7 @@ static int lm87_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, lm87_detect); return i2c_probe(adapter, &addr_data, lm87_detect);
} }
/* /*
...@@ -608,6 +609,12 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -608,6 +609,12 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
data->in_scale[7] = 1875; data->in_scale[7] = 1875;
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_in1_input); device_create_file(&new_client->dev, &dev_attr_in1_input);
device_create_file(&new_client->dev, &dev_attr_in1_min); device_create_file(&new_client->dev, &dev_attr_in1_min);
device_create_file(&new_client->dev, &dev_attr_in1_max); device_create_file(&new_client->dev, &dev_attr_in1_max);
...@@ -673,6 +680,8 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -673,6 +680,8 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -685,7 +694,7 @@ static void lm87_init_client(struct i2c_client *client) ...@@ -685,7 +694,7 @@ static void lm87_init_client(struct i2c_client *client)
u8 config; u8 config;
data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE); data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
data->vrm = i2c_which_vrm(); data->vrm = vid_which_vrm();
config = lm87_read_value(client, LM87_REG_CONFIG); config = lm87_read_value(client, LM87_REG_CONFIG);
if (!(config & 0x01)) { if (!(config & 0x01)) {
...@@ -719,15 +728,15 @@ static void lm87_init_client(struct i2c_client *client) ...@@ -719,15 +728,15 @@ static void lm87_init_client(struct i2c_client *client)
static int lm87_detach_client(struct i2c_client *client) static int lm87_detach_client(struct i2c_client *client)
{ {
struct lm87_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -75,8 +75,9 @@ ...@@ -75,8 +75,9 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -89,13 +90,12 @@ ...@@ -89,13 +90,12 @@
*/ */
static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* /*
* Insmod parameters * Insmod parameters
*/ */
SENSORS_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461); I2C_CLIENT_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461);
/* /*
* The LM90 registers * The LM90 registers
...@@ -200,6 +200,7 @@ static struct i2c_driver lm90_driver = { ...@@ -200,6 +200,7 @@ static struct i2c_driver lm90_driver = {
struct lm90_data { struct lm90_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
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 */
...@@ -352,7 +353,7 @@ static int lm90_attach_adapter(struct i2c_adapter *adapter) ...@@ -352,7 +353,7 @@ static int lm90_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, lm90_detect); return i2c_probe(adapter, &addr_data, lm90_detect);
} }
/* /*
...@@ -500,6 +501,12 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -500,6 +501,12 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
lm90_init_client(new_client); lm90_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_temp1_input.dev_attr); &sensor_dev_attr_temp1_input.dev_attr);
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
...@@ -524,6 +531,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -524,6 +531,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -547,15 +556,15 @@ static void lm90_init_client(struct i2c_client *client) ...@@ -547,15 +556,15 @@ static void lm90_init_client(struct i2c_client *client)
static int lm90_detach_client(struct i2c_client *client) static int lm90_detach_client(struct i2c_client *client)
{ {
struct lm90_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -44,17 +44,16 @@ ...@@ -44,17 +44,16 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
/* The LM92 and MAX6635 have 2 two-state pins for address selection, /* The LM92 and MAX6635 have 2 two-state pins for address selection,
resulting in 4 possible addresses. */ resulting in 4 possible addresses. */
static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
I2C_CLIENT_END }; I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */ /* Insmod parameters */
SENSORS_INSMOD_1(lm92); I2C_CLIENT_INSMOD_1(lm92);
/* The LM92 registers */ /* The LM92 registers */
#define LM92_REG_CONFIG 0x01 /* 8-bit, RW */ #define LM92_REG_CONFIG 0x01 /* 8-bit, RW */
...@@ -96,6 +95,7 @@ static struct i2c_driver lm92_driver; ...@@ -96,6 +95,7 @@ static struct i2c_driver lm92_driver;
/* Client data (each client gets its own) */ /* Client data (each client gets its own) */
struct lm92_data { struct lm92_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
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 */
...@@ -359,6 +359,12 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -359,6 +359,12 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
lm92_init_client(new_client); lm92_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp1_crit); device_create_file(&new_client->dev, &dev_attr_temp1_crit);
device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst); device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
...@@ -370,6 +376,8 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -370,6 +376,8 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -380,20 +388,20 @@ static int lm92_attach_adapter(struct i2c_adapter *adapter) ...@@ -380,20 +388,20 @@ static int lm92_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, lm92_detect); return i2c_probe(adapter, &addr_data, lm92_detect);
} }
static int lm92_detach_client(struct i2c_client *client) static int lm92_detach_client(struct i2c_client *client)
{ {
struct lm92_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -31,20 +31,19 @@ ...@@ -31,20 +31,19 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
0x29, 0x2a, 0x2b, 0x29, 0x2a, 0x2b,
0x4c, 0x4d, 0x4e, 0x4c, 0x4d, 0x4e,
I2C_CLIENT_END }; I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* /*
* Insmod parameters * Insmod parameters
*/ */
SENSORS_INSMOD_1(max1619); I2C_CLIENT_INSMOD_1(max1619);
/* /*
* The MAX1619 registers * The MAX1619 registers
...@@ -104,6 +103,7 @@ static struct i2c_driver max1619_driver = { ...@@ -104,6 +103,7 @@ static struct i2c_driver max1619_driver = {
struct max1619_data { struct max1619_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
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 */
...@@ -179,7 +179,7 @@ static int max1619_attach_adapter(struct i2c_adapter *adapter) ...@@ -179,7 +179,7 @@ static int max1619_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, max1619_detect); return i2c_probe(adapter, &addr_data, max1619_detect);
} }
/* /*
...@@ -275,6 +275,12 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -275,6 +275,12 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
max1619_init_client(new_client); max1619_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp2_input); device_create_file(&new_client->dev, &dev_attr_temp2_input);
device_create_file(&new_client->dev, &dev_attr_temp2_min); device_create_file(&new_client->dev, &dev_attr_temp2_min);
...@@ -285,6 +291,8 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -285,6 +291,8 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -308,15 +316,15 @@ static void max1619_init_client(struct i2c_client *client) ...@@ -308,15 +316,15 @@ static void max1619_init_client(struct i2c_client *client)
static int max1619_detach_client(struct i2c_client *client) static int max1619_detach_client(struct i2c_client *client)
{ {
struct max1619_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -55,7 +55,9 @@ ...@@ -55,7 +55,9 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-isa.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -68,14 +70,10 @@ module_param(force_addr, ushort, 0); ...@@ -68,14 +70,10 @@ module_param(force_addr, ushort, 0);
MODULE_PARM_DESC(force_addr, MODULE_PARM_DESC(force_addr,
"Initialize the base address of the sensors"); "Initialize the base address of the sensors");
/* Addresses to scan. /* Device address
Note that we can't determine the ISA address until we have initialized Note that we can't determine the ISA address until we have initialized
our module */ our module */
static unsigned short normal_i2c[] = { I2C_CLIENT_END }; static unsigned short address;
static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
/* Insmod parameters */
SENSORS_INSMOD_1(sis5595);
/* Many SIS5595 constants specified below */ /* Many SIS5595 constants specified below */
...@@ -168,6 +166,7 @@ static inline u8 DIV_TO_REG(int val) ...@@ -168,6 +166,7 @@ static inline u8 DIV_TO_REG(int val)
allocated. */ allocated. */
struct sis5595_data { struct sis5595_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -190,8 +189,7 @@ struct sis5595_data { ...@@ -190,8 +189,7 @@ struct sis5595_data {
static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */ static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */
static int sis5595_attach_adapter(struct i2c_adapter *adapter); static int sis5595_detect(struct i2c_adapter *adapter);
static int sis5595_detect(struct i2c_adapter *adapter, int address, int kind);
static int sis5595_detach_client(struct i2c_client *client); static int sis5595_detach_client(struct i2c_client *client);
static int sis5595_read_value(struct i2c_client *client, u8 register); static int sis5595_read_value(struct i2c_client *client, u8 register);
...@@ -202,9 +200,7 @@ static void sis5595_init_client(struct i2c_client *client); ...@@ -202,9 +200,7 @@ static void sis5595_init_client(struct i2c_client *client);
static struct i2c_driver sis5595_driver = { static struct i2c_driver sis5595_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "sis5595", .name = "sis5595",
.id = I2C_DRIVERID_SIS5595, .attach_adapter = sis5595_detect,
.flags = I2C_DF_NOTIFY,
.attach_adapter = sis5595_attach_adapter,
.detach_client = sis5595_detach_client, .detach_client = sis5595_detach_client,
}; };
...@@ -476,14 +472,7 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch ...@@ -476,14 +472,7 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
/* This is called when the module is loaded */ /* This is called when the module is loaded */
static int sis5595_attach_adapter(struct i2c_adapter *adapter) static int sis5595_detect(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_detect(adapter, &addr_data, sis5595_detect);
}
int sis5595_detect(struct i2c_adapter *adapter, int address, int kind)
{ {
int err = 0; int err = 0;
int i; int i;
...@@ -492,10 +481,6 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -492,10 +481,6 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind)
char val; char val;
u16 a; u16 a;
/* Make sure we are probing the ISA bus!! */
if (!i2c_is_isa_adapter(adapter))
goto exit;
if (force_addr) if (force_addr)
address = force_addr & ~(SIS5595_EXTENT - 1); address = force_addr & ~(SIS5595_EXTENT - 1);
/* Reserve the ISA region */ /* Reserve the ISA region */
...@@ -578,6 +563,12 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -578,6 +563,12 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind)
} }
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
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);
device_create_file(&new_client->dev, &dev_attr_in0_max); device_create_file(&new_client->dev, &dev_attr_in0_max);
...@@ -608,7 +599,9 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -608,7 +599,9 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
} }
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit_release: exit_release:
...@@ -619,18 +612,17 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -619,18 +612,17 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind)
static int sis5595_detach_client(struct i2c_client *client) static int sis5595_detach_client(struct i2c_client *client)
{ {
struct sis5595_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev,
"Client deregistration failed, client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
if (i2c_is_isa_client(client)) release_region(client->addr, SIS5595_EXTENT);
release_region(client->addr, SIS5595_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
...@@ -745,7 +737,6 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev, ...@@ -745,7 +737,6 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev,
{ {
u16 val; u16 val;
int *i; int *i;
int addr = 0;
for (i = blacklist; *i != 0; i++) { for (i = blacklist; *i != 0; i++) {
struct pci_dev *dev; struct pci_dev *dev;
...@@ -761,22 +752,19 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev, ...@@ -761,22 +752,19 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev,
pci_read_config_word(dev, SIS5595_BASE_REG, &val)) pci_read_config_word(dev, SIS5595_BASE_REG, &val))
return -ENODEV; return -ENODEV;
addr = val & ~(SIS5595_EXTENT - 1); address = val & ~(SIS5595_EXTENT - 1);
if (addr == 0 && force_addr == 0) { if (address == 0 && force_addr == 0) {
dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n"); dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n");
return -ENODEV; return -ENODEV;
} }
if (force_addr)
addr = force_addr; /* so detect will get called */
if (!addr) { if (!address) {
dev_err(&dev->dev,"No SiS 5595 sensors found.\n"); dev_err(&dev->dev,"No SiS 5595 sensors found.\n");
return -ENODEV; return -ENODEV;
} }
normal_isa[0] = addr;
s_bridge = pci_dev_get(dev); s_bridge = pci_dev_get(dev);
if (i2c_add_driver(&sis5595_driver)) { if (i2c_isa_add_driver(&sis5595_driver)) {
pci_dev_put(s_bridge); pci_dev_put(s_bridge);
s_bridge = NULL; s_bridge = NULL;
} }
...@@ -803,7 +791,7 @@ static void __exit sm_sis5595_exit(void) ...@@ -803,7 +791,7 @@ static void __exit sm_sis5595_exit(void)
{ {
pci_unregister_driver(&sis5595_pci_driver); pci_unregister_driver(&sis5595_pci_driver);
if (s_bridge != NULL) { if (s_bridge != NULL) {
i2c_del_driver(&sis5595_driver); i2c_isa_del_driver(&sis5595_driver);
pci_dev_put(s_bridge); pci_dev_put(s_bridge);
s_bridge = NULL; s_bridge = NULL;
} }
......
...@@ -31,23 +31,14 @@ ...@@ -31,23 +31,14 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-isa.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/io.h> #include <asm/io.h>
static unsigned short normal_i2c[] = { I2C_CLIENT_END };
/* Address is autodetected, there is no default value */ /* Address is autodetected, there is no default value */
static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END }; static unsigned short address;
static struct i2c_force_data forces[] = {{NULL}};
enum chips { any_chip, smsc47b397 };
static struct i2c_address_data addr_data = {
.normal_i2c = normal_i2c,
.normal_isa = normal_isa,
.probe = normal_i2c, /* cheat */
.ignore = normal_i2c, /* cheat */
.forces = forces,
};
/* Super-I/0 registers and commands */ /* Super-I/0 registers and commands */
...@@ -100,6 +91,7 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80}; ...@@ -100,6 +91,7 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80};
struct smsc47b397_data { struct smsc47b397_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -215,52 +207,40 @@ sysfs_fan(4); ...@@ -215,52 +207,40 @@ sysfs_fan(4);
#define device_create_file_fan(client, num) \ #define device_create_file_fan(client, num) \
device_create_file(&client->dev, &dev_attr_fan##num##_input) device_create_file(&client->dev, &dev_attr_fan##num##_input)
static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind);
static int smsc47b397_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_detect(adapter, &addr_data, smsc47b397_detect);
}
static int smsc47b397_detach_client(struct i2c_client *client) static int smsc47b397_detach_client(struct i2c_client *client)
{ {
struct smsc47b397_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
release_region(client->addr, SMSC_EXTENT); release_region(client->addr, SMSC_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
static int smsc47b397_detect(struct i2c_adapter *adapter);
static struct i2c_driver smsc47b397_driver = { static struct i2c_driver smsc47b397_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "smsc47b397", .name = "smsc47b397",
.id = I2C_DRIVERID_SMSC47B397, .attach_adapter = smsc47b397_detect,
.flags = I2C_DF_NOTIFY,
.attach_adapter = smsc47b397_attach_adapter,
.detach_client = smsc47b397_detach_client, .detach_client = smsc47b397_detach_client,
}; };
static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) static int smsc47b397_detect(struct i2c_adapter *adapter)
{ {
struct i2c_client *new_client; struct i2c_client *new_client;
struct smsc47b397_data *data; struct smsc47b397_data *data;
int err = 0; int err = 0;
if (!i2c_is_isa_adapter(adapter)) { if (!request_region(address, SMSC_EXTENT, smsc47b397_driver.name)) {
return 0; dev_err(&adapter->dev, "Region 0x%x already in use!\n",
} address);
if (!request_region(addr, SMSC_EXTENT, smsc47b397_driver.name)) {
dev_err(&adapter->dev, "Region 0x%x already in use!\n", addr);
return -EBUSY; return -EBUSY;
} }
...@@ -272,7 +252,7 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) ...@@ -272,7 +252,7 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
new_client = &data->client; new_client = &data->client;
i2c_set_clientdata(new_client, data); i2c_set_clientdata(new_client, data);
new_client->addr = addr; new_client->addr = address;
init_MUTEX(&data->lock); init_MUTEX(&data->lock);
new_client->adapter = adapter; new_client->adapter = adapter;
new_client->driver = &smsc47b397_driver; new_client->driver = &smsc47b397_driver;
...@@ -285,6 +265,12 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) ...@@ -285,6 +265,12 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto error_free; goto error_free;
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto error_detach;
}
device_create_file_temp(new_client, 1); device_create_file_temp(new_client, 1);
device_create_file_temp(new_client, 2); device_create_file_temp(new_client, 2);
device_create_file_temp(new_client, 3); device_create_file_temp(new_client, 3);
...@@ -297,14 +283,16 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) ...@@ -297,14 +283,16 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
return 0; return 0;
error_detach:
i2c_detach_client(new_client);
error_free: error_free:
kfree(data); kfree(data);
error_release: error_release:
release_region(addr, SMSC_EXTENT); release_region(address, SMSC_EXTENT);
return err; return err;
} }
static int __init smsc47b397_find(unsigned int *addr) static int __init smsc47b397_find(unsigned short *addr)
{ {
u8 id, rev; u8 id, rev;
...@@ -333,15 +321,15 @@ static int __init smsc47b397_init(void) ...@@ -333,15 +321,15 @@ static int __init smsc47b397_init(void)
{ {
int ret; int ret;
if ((ret = smsc47b397_find(normal_isa))) if ((ret = smsc47b397_find(&address)))
return ret; return ret;
return i2c_add_driver(&smsc47b397_driver); return i2c_isa_add_driver(&smsc47b397_driver);
} }
static void __exit smsc47b397_exit(void) static void __exit smsc47b397_exit(void)
{ {
i2c_del_driver(&smsc47b397_driver); i2c_isa_del_driver(&smsc47b397_driver);
} }
MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
......
...@@ -30,21 +30,14 @@ ...@@ -30,21 +30,14 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-isa.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/io.h> #include <asm/io.h>
static unsigned short normal_i2c[] = { I2C_CLIENT_END };
/* Address is autodetected, there is no default value */ /* Address is autodetected, there is no default value */
static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END }; static unsigned short address;
static struct i2c_force_data forces[] = {{NULL}};
enum chips { any_chip, smsc47m1 };
static struct i2c_address_data addr_data = {
.normal_i2c = normal_i2c,
.normal_isa = normal_isa,
.forces = forces,
};
/* Super-I/0 registers and commands */ /* Super-I/0 registers and commands */
...@@ -108,6 +101,7 @@ superio_exit(void) ...@@ -108,6 +101,7 @@ superio_exit(void)
struct smsc47m1_data { struct smsc47m1_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -121,9 +115,7 @@ struct smsc47m1_data { ...@@ -121,9 +115,7 @@ struct smsc47m1_data {
}; };
static int smsc47m1_attach_adapter(struct i2c_adapter *adapter); static int smsc47m1_detect(struct i2c_adapter *adapter);
static int smsc47m1_find(int *address);
static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind);
static int smsc47m1_detach_client(struct i2c_client *client); static int smsc47m1_detach_client(struct i2c_client *client);
static int smsc47m1_read_value(struct i2c_client *client, u8 reg); static int smsc47m1_read_value(struct i2c_client *client, u8 reg);
...@@ -136,9 +128,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, ...@@ -136,9 +128,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
static struct i2c_driver smsc47m1_driver = { static struct i2c_driver smsc47m1_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "smsc47m1", .name = "smsc47m1",
.id = I2C_DRIVERID_SMSC47M1, .attach_adapter = smsc47m1_detect,
.flags = I2C_DF_NOTIFY,
.attach_adapter = smsc47m1_attach_adapter,
.detach_client = smsc47m1_detach_client, .detach_client = smsc47m1_detach_client,
}; };
...@@ -354,14 +344,7 @@ fan_present(2); ...@@ -354,14 +344,7 @@ fan_present(2);
static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
static int smsc47m1_attach_adapter(struct i2c_adapter *adapter) static int __init smsc47m1_find(unsigned short *addr)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_detect(adapter, &addr_data, smsc47m1_detect);
}
static int smsc47m1_find(int *address)
{ {
u8 val; u8 val;
...@@ -388,10 +371,10 @@ static int smsc47m1_find(int *address) ...@@ -388,10 +371,10 @@ static int smsc47m1_find(int *address)
} }
superio_select(); superio_select();
*address = (superio_inb(SUPERIO_REG_BASE) << 8) *addr = (superio_inb(SUPERIO_REG_BASE) << 8)
| superio_inb(SUPERIO_REG_BASE + 1); | superio_inb(SUPERIO_REG_BASE + 1);
val = superio_inb(SUPERIO_REG_ACT); val = superio_inb(SUPERIO_REG_ACT);
if (*address == 0 || (val & 0x01) == 0) { if (*addr == 0 || (val & 0x01) == 0) {
printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n"); printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n");
superio_exit(); superio_exit();
return -ENODEV; return -ENODEV;
...@@ -401,17 +384,13 @@ static int smsc47m1_find(int *address) ...@@ -401,17 +384,13 @@ static int smsc47m1_find(int *address)
return 0; return 0;
} }
static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) static int smsc47m1_detect(struct i2c_adapter *adapter)
{ {
struct i2c_client *new_client; struct i2c_client *new_client;
struct smsc47m1_data *data; struct smsc47m1_data *data;
int err = 0; int err = 0;
int fan1, fan2, pwm1, pwm2; int fan1, fan2, pwm1, pwm2;
if (!i2c_is_isa_adapter(adapter)) {
return 0;
}
if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) { if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) {
dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); dev_err(&adapter->dev, "Region 0x%x already in use!\n", address);
return -EBUSY; return -EBUSY;
...@@ -461,6 +440,13 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -461,6 +440,13 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
function. */ function. */
smsc47m1_update_device(&new_client->dev, 1); smsc47m1_update_device(&new_client->dev, 1);
/* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto error_detach;
}
if (fan1) { if (fan1) {
device_create_file(&new_client->dev, &dev_attr_fan1_input); device_create_file(&new_client->dev, &dev_attr_fan1_input);
device_create_file(&new_client->dev, &dev_attr_fan1_min); device_create_file(&new_client->dev, &dev_attr_fan1_min);
...@@ -494,6 +480,8 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -494,6 +480,8 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
error_detach:
i2c_detach_client(new_client);
error_free: error_free:
kfree(data); kfree(data);
error_release: error_release:
...@@ -503,16 +491,16 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -503,16 +491,16 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
static int smsc47m1_detach_client(struct i2c_client *client) static int smsc47m1_detach_client(struct i2c_client *client)
{ {
struct smsc47m1_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
release_region(client->addr, SMSC_EXTENT); release_region(client->addr, SMSC_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
...@@ -573,16 +561,16 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, ...@@ -573,16 +561,16 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
static int __init sm_smsc47m1_init(void) static int __init sm_smsc47m1_init(void)
{ {
if (smsc47m1_find(normal_isa)) { if (smsc47m1_find(&address)) {
return -ENODEV; return -ENODEV;
} }
return i2c_add_driver(&smsc47m1_driver); return i2c_isa_add_driver(&smsc47m1_driver);
} }
static void __exit sm_smsc47m1_exit(void) static void __exit sm_smsc47m1_exit(void)
{ {
i2c_del_driver(&smsc47m1_driver); i2c_isa_del_driver(&smsc47m1_driver);
} }
MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>"); MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -36,7 +36,8 @@ ...@@ -36,7 +36,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/hwmon.h>
#include <linux/err.h>
/* How many retries on register read error */ /* How many retries on register read error */
#define MAX_RETRIES 5 #define MAX_RETRIES 5
...@@ -47,13 +48,12 @@ ...@@ -47,13 +48,12 @@
*/ */
static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
/* /*
* Insmod parameters * Insmod parameters
*/ */
SENSORS_INSMOD_1(w83l785ts); I2C_CLIENT_INSMOD_1(w83l785ts);
/* /*
* The W83L785TS-S registers * The W83L785TS-S registers
...@@ -105,6 +105,7 @@ static struct i2c_driver w83l785ts_driver = { ...@@ -105,6 +105,7 @@ static struct i2c_driver w83l785ts_driver = {
struct w83l785ts_data { struct w83l785ts_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
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 */
...@@ -140,7 +141,7 @@ static int w83l785ts_attach_adapter(struct i2c_adapter *adapter) ...@@ -140,7 +141,7 @@ static int w83l785ts_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_CLASS_HWMON)) if (!(adapter->class & I2C_CLASS_HWMON))
return 0; return 0;
return i2c_detect(adapter, &addr_data, w83l785ts_detect); return i2c_probe(adapter, &addr_data, w83l785ts_detect);
} }
/* /*
...@@ -239,11 +240,19 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -239,11 +240,19 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
*/ */
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp1_max); device_create_file(&new_client->dev, &dev_attr_temp1_max);
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -252,15 +261,15 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -252,15 +261,15 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
static int w83l785ts_detach_client(struct i2c_client *client) static int w83l785ts_detach_client(struct i2c_client *client)
{ {
struct w83l785ts_data *data = i2c_get_clientdata(client);
int err; int err;
if ((err = i2c_detach_client(client))) { hwmon_device_unregister(data->class_dev);
dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); if ((err = i2c_detach_client(client)))
return err; return err;
}
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -4,12 +4,8 @@ ...@@ -4,12 +4,8 @@
obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C) += i2c-core.o
obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
obj-$(CONFIG_I2C_SENSOR) += i2c-sensor.o
obj-y += busses/ chips/ algos/ obj-y += busses/ chips/ algos/
i2c-sensor-objs := i2c-sensor-detect.o i2c-sensor-vid.o
ifeq ($(CONFIG_I2C_DEBUG_CORE),y) ifeq ($(CONFIG_I2C_DEBUG_CORE),y)
EXTRA_CFLAGS += -DDEBUG EXTRA_CFLAGS += -DDEBUG
endif endif
...@@ -519,8 +519,6 @@ static u32 bit_func(struct i2c_adapter *adap) ...@@ -519,8 +519,6 @@ static u32 bit_func(struct i2c_adapter *adap)
/* -----exported algorithm data: ------------------------------------- */ /* -----exported algorithm data: ------------------------------------- */
static struct i2c_algorithm i2c_bit_algo = { static struct i2c_algorithm i2c_bit_algo = {
.name = "Bit-shift algorithm",
.id = I2C_ALGO_BIT,
.master_xfer = bit_xfer, .master_xfer = bit_xfer,
.functionality = bit_func, .functionality = bit_func,
}; };
...@@ -541,8 +539,6 @@ int i2c_bit_add_bus(struct i2c_adapter *adap) ...@@ -541,8 +539,6 @@ int i2c_bit_add_bus(struct i2c_adapter *adap)
DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); DEB2(dev_dbg(&adap->dev, "hw routines registered.\n"));
/* register new adapter to i2c module... */ /* register new adapter to i2c module... */
adap->id |= i2c_bit_algo.id;
adap->algo = &i2c_bit_algo; adap->algo = &i2c_bit_algo;
adap->timeout = 100; /* default values, should */ adap->timeout = 100; /* default values, should */
......
...@@ -713,8 +713,6 @@ static u32 iic_func(struct i2c_adapter *adap) ...@@ -713,8 +713,6 @@ static u32 iic_func(struct i2c_adapter *adap)
/* -----exported algorithm data: ------------------------------------- */ /* -----exported algorithm data: ------------------------------------- */
static struct i2c_algorithm iic_algo = { static struct i2c_algorithm iic_algo = {
.name = "ITE IIC algorithm",
.id = I2C_ALGO_IIC,
.master_xfer = iic_xfer, .master_xfer = iic_xfer,
.algo_control = algo_control, /* ioctl */ .algo_control = algo_control, /* ioctl */
.functionality = iic_func, .functionality = iic_func,
...@@ -738,8 +736,6 @@ int i2c_iic_add_bus(struct i2c_adapter *adap) ...@@ -738,8 +736,6 @@ int i2c_iic_add_bus(struct i2c_adapter *adap)
adap->name)); adap->name));
/* register new adapter to i2c module... */ /* register new adapter to i2c module... */
adap->id |= iic_algo.id;
adap->algo = &iic_algo; adap->algo = &iic_algo;
adap->timeout = 100; /* default values, should */ adap->timeout = 100; /* default values, should */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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