mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
Auto-update from upstream
This commit is contained in:
commit
add5b5ee99
221 changed files with 3861 additions and 2254 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -10,6 +10,7 @@
|
|||
*.a
|
||||
*.s
|
||||
*.ko
|
||||
*.so
|
||||
*.mod.c
|
||||
|
||||
#
|
||||
|
|
|
@ -71,15 +71,6 @@ Who: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
|
|||
|
||||
---------------------------
|
||||
|
||||
What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
|
||||
When: November 2005
|
||||
Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
|
||||
Why: Match the other drivers' name for the same function, duplicate names
|
||||
will be available until removal of old names.
|
||||
Who: Grant Coady <gcoady@gmail.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: remove EXPORT_SYMBOL(panic_timeout)
|
||||
When: April 2006
|
||||
Files: kernel/panic.c
|
||||
|
|
|
@ -54,13 +54,16 @@ If you really want i2c accesses for these Super I/O chips,
|
|||
use the w83781d driver. However this is not the preferred method
|
||||
now that this ISA driver has been developed.
|
||||
|
||||
Technically, the w83627thf does not support a VID reading. However, it's
|
||||
possible or even likely that your mainboard maker has routed these signals
|
||||
to a specific set of general purpose IO pins (the Asus P4C800-E is one such
|
||||
board). The w83627thf driver now interprets these as VID. If the VID on
|
||||
your board doesn't work, first see doc/vid in the lm_sensors package. If
|
||||
that still doesn't help, email us at lm-sensors@lm-sensors.org.
|
||||
The w83627_HF_ uses pins 110-106 as VID0-VID4. The w83627_THF_ uses the
|
||||
same pins as GPIO[0:4]. Technically, the w83627_THF_ does not support a
|
||||
VID reading. However the two chips have the identical 128 pin package. So,
|
||||
it is possible or even likely for a w83627thf to have the VID signals routed
|
||||
to these pins despite their not being labeled for that purpose. Therefore,
|
||||
the w83627thf driver interprets these as VID. If the VID on your board
|
||||
doesn't work, first see doc/vid in the lm_sensors package[1]. If that still
|
||||
doesn't help, you may just ignore the bogus VID reading with no harm done.
|
||||
|
||||
For further information on this driver see the w83781d driver
|
||||
documentation.
|
||||
For further information on this driver see the w83781d driver documentation.
|
||||
|
||||
[1] http://www2.lm-sensors.nu/~lm78/cvs/browse.cgi/lm_sensors2/doc/vid
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ Supported adapters:
|
|||
* nForce2 Ultra 400 MCP 10de:0084
|
||||
* nForce3 Pro150 MCP 10de:00D4
|
||||
* nForce3 250Gb MCP 10de:00E4
|
||||
* nForce4 MCP 10de:0052
|
||||
* nForce4 MCP 10de:0052
|
||||
* nForce4 MCP-04 10de:0034
|
||||
|
||||
Datasheet: not publically available, but seems to be similar to the
|
||||
AMD-8111 SMBus 2.0 adapter.
|
||||
|
|
|
@ -17,6 +17,7 @@ It currently supports the following devices:
|
|||
* Velleman K8000 adapter
|
||||
* ELV adapter
|
||||
* Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032)
|
||||
* Barco LPT->DVI (K5800236) adapter
|
||||
|
||||
These devices use different pinout configurations, so you have to tell
|
||||
the driver what you have, using the type module parameter. There is no
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
Revision 5, 2005-07-29
|
||||
Revision 6, 2005-11-20
|
||||
Jean Delvare <khali@linux-fr.org>
|
||||
Greg KH <greg@kroah.com>
|
||||
|
||||
This is a guide on how to convert I2C chip drivers from Linux 2.4 to
|
||||
Linux 2.6. I have been using existing drivers (lm75, lm78) as examples.
|
||||
Then I converted a driver myself (lm83) and updated this document.
|
||||
Note that this guide is strongly oriented towards hardware monitoring
|
||||
drivers. Many points are still valid for other type of drivers, but
|
||||
others may be irrelevant.
|
||||
|
||||
There are two sets of points below. The first set concerns technical
|
||||
changes. The second set concerns coding policy. Both are mandatory.
|
||||
|
@ -22,16 +25,20 @@ Technical changes:
|
|||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-isa.h> /* for ISA drivers */
|
||||
#include <linux/hwmon.h> /* for hardware monitoring drivers */
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/hwmon-vid.h> /* if you need VRM support */
|
||||
#include <linux/err.h> /* for class registration */
|
||||
#include <asm/io.h> /* if you have I/O operations */
|
||||
Please respect this inclusion order. Some extra headers may be
|
||||
required for a given driver (e.g. "lm75.h").
|
||||
|
||||
* [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, ISA addresses
|
||||
are no more handled by the i2c core.
|
||||
are no more handled by the i2c core. Address ranges are no more
|
||||
supported either, define each individual address separately.
|
||||
SENSORS_INSMOD_<n> becomes I2C_CLIENT_INSMOD_<n>.
|
||||
|
||||
* [Client data] Get rid of sysctl_id. Try using standard names for
|
||||
|
@ -48,23 +55,23 @@ Technical changes:
|
|||
int kind);
|
||||
static void lm75_init_client(struct i2c_client *client);
|
||||
static int lm75_detach_client(struct i2c_client *client);
|
||||
static void lm75_update_client(struct i2c_client *client);
|
||||
static struct lm75_data lm75_update_device(struct device *dev);
|
||||
|
||||
* [Sysctl] All sysctl stuff is of course gone (defines, ctl_table
|
||||
and functions). Instead, you have to define show and set functions for
|
||||
each sysfs file. Only define set for writable values. Take a look at an
|
||||
existing 2.6 driver for details (lm78 for example). Don't forget
|
||||
existing 2.6 driver for details (it87 for example). Don't forget
|
||||
to define the attributes for each file (this is that step that
|
||||
links callback functions). Use the file names specified in
|
||||
Documentation/i2c/sysfs-interface for the individual files. Also
|
||||
Documentation/hwmon/sysfs-interface for the individual files. Also
|
||||
convert the units these files read and write to the specified ones.
|
||||
If you need to add a new type of file, please discuss it on the
|
||||
sensors mailing list <lm-sensors@lm-sensors.org> by providing a
|
||||
patch to the Documentation/i2c/sysfs-interface file.
|
||||
patch to the Documentation/hwmon/sysfs-interface file.
|
||||
|
||||
* [Attach] For I2C drivers, the attach function should make sure
|
||||
that the adapter's class has I2C_CLASS_HWMON, using the
|
||||
following construct:
|
||||
that the adapter's class has I2C_CLASS_HWMON (or whatever class is
|
||||
suitable for your driver), using the following construct:
|
||||
if (!(adapter->class & I2C_CLASS_HWMON))
|
||||
return 0;
|
||||
ISA-only drivers of course don't need this.
|
||||
|
@ -72,63 +79,72 @@ Technical changes:
|
|||
|
||||
* [Detect] As mentioned earlier, the flags parameter is gone.
|
||||
The type_name and client_name strings are replaced by a single
|
||||
name string, which will be filled with a lowercase, short string
|
||||
(typically the driver name, e.g. "lm75").
|
||||
name string, which will be filled with a lowercase, short string.
|
||||
In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
|
||||
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
|
||||
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
|
||||
ERROR0, ERROR1 and ERROR2. Don't forget to properly set err before
|
||||
The labels used for error paths are reduced to the number needed.
|
||||
It is advised that the labels are given descriptive names such as
|
||||
exit and exit_free. Don't forget to properly set err before
|
||||
jumping to error labels. By the way, labels should be left-aligned.
|
||||
Use kzalloc instead of kmalloc.
|
||||
Use i2c_set_clientdata to set the client data (as opposed to
|
||||
a direct access to client->data).
|
||||
Use strlcpy instead of strcpy to copy the client name.
|
||||
Use strlcpy instead of strcpy or snprintf to copy the client name.
|
||||
Replace the sysctl directory registration by calls to
|
||||
device_create_file. Move the driver initialization before any
|
||||
sysfs file creation.
|
||||
Register the client with the hwmon class (using hwmon_device_register)
|
||||
if applicable.
|
||||
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.
|
||||
Don't add I2C_CLIENT_ALLOW_USE to client->flags, it's the default now.
|
||||
|
||||
* [Init] Limits must not be set by the driver (can be done later in
|
||||
user-space). Chip should not be reset default (although a module
|
||||
parameter may be used to force is), and initialization should be
|
||||
parameter may be used to force it), and initialization should be
|
||||
limited to the strictly necessary steps.
|
||||
|
||||
* [Detach] Get rid of data, remove the call to
|
||||
i2c_deregister_entry. Do not log an error message if
|
||||
i2c_detach_client fails, as i2c-core will now do it for you.
|
||||
* [Detach] Remove the call to i2c_deregister_entry. Do not log an
|
||||
error message if i2c_detach_client fails, as i2c-core will now do
|
||||
it for you.
|
||||
Unregister from the hwmon class if applicable.
|
||||
|
||||
* [Update] Don't access client->data directly, use
|
||||
i2c_get_clientdata(client) instead.
|
||||
* [Update] The function prototype changed, it is now
|
||||
passed a device structure, which you have to convert to a client
|
||||
using to_i2c_client(dev). The update function should return a
|
||||
pointer to the client data.
|
||||
Don't access client->data directly, use i2c_get_clientdata(client)
|
||||
instead.
|
||||
Use time_after() instead of direct jiffies comparison.
|
||||
|
||||
* [Interface] Init function should not print anything. Make sure
|
||||
there is a MODULE_LICENSE() line, at the bottom of the file
|
||||
(after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this order).
|
||||
* [Interface] Make sure there is a MODULE_LICENSE() line, at the bottom
|
||||
of the file (after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this
|
||||
order).
|
||||
|
||||
* [Driver] The flags field of the i2c_driver structure is gone.
|
||||
I2C_DF_NOTIFY is now the default behavior.
|
||||
The i2c_driver structure has a driver member, which is itself a
|
||||
structure, those name member should be initialized to a driver name
|
||||
string. i2c_driver itself has no name member anymore.
|
||||
|
||||
Coding policy:
|
||||
|
||||
* [Copyright] Use (C), not (c), for copyright.
|
||||
|
||||
* [Debug/log] Get rid of #ifdef DEBUG/#endif constructs whenever you
|
||||
can. Calls to printk/pr_debug for debugging purposes are replaced
|
||||
by calls to dev_dbg. Here is an example on how to call it (taken
|
||||
from lm75_detect):
|
||||
can. Calls to printk for debugging purposes are replaced by calls to
|
||||
dev_dbg where possible, else to pr_debug. Here is an example of how
|
||||
to call it (taken from lm75_detect):
|
||||
dev_dbg(&client->dev, "Starting lm75 update\n");
|
||||
Replace other printk calls with the dev_info, dev_err or dev_warn
|
||||
function, as appropriate.
|
||||
|
||||
* [Constants] Constants defines (registers, conversions, initial
|
||||
values) should be aligned. This greatly improves readability.
|
||||
Same goes for variables declarations. Alignments are achieved by the
|
||||
means of tabs, not spaces. Remember that tabs are set to 8 in the
|
||||
Linux kernel code.
|
||||
|
||||
* [Structure definition] The name field should be standardized. All
|
||||
lowercase and as simple as the driver name itself (e.g. "lm75").
|
||||
* [Constants] Constants defines (registers, conversions) should be
|
||||
aligned. This greatly improves readability.
|
||||
Alignments are achieved by the means of tabs, not spaces. Remember
|
||||
that tabs are set to 8 in the Linux kernel code.
|
||||
|
||||
* [Layout] Avoid extra empty lines between comments and what they
|
||||
comment. Respect the coding style (see Documentation/CodingStyle),
|
||||
|
|
|
@ -25,9 +25,9 @@ routines, a client structure specific information like the actual I2C
|
|||
address.
|
||||
|
||||
static struct i2c_driver foo_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "Foo version 2.3 driver",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "foo",
|
||||
},
|
||||
.attach_adapter = &foo_attach_adapter,
|
||||
.detach_client = &foo_detach_client,
|
||||
.command = &foo_command /* may be NULL */
|
||||
|
@ -36,10 +36,6 @@ static struct i2c_driver foo_driver = {
|
|||
The name field must match the driver name, including the case. It must not
|
||||
contain spaces, and may be up to 31 characters long.
|
||||
|
||||
Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This
|
||||
means that your driver will be notified when new adapters are found.
|
||||
This is almost always what you want.
|
||||
|
||||
All other fields are for call-back functions which will be explained
|
||||
below.
|
||||
|
||||
|
@ -496,17 +492,13 @@ Note that some functions are marked by `__init', and some data structures
|
|||
by `__init_data'. Hose functions and structures can be removed after
|
||||
kernel booting (or module loading) is completed.
|
||||
|
||||
|
||||
Command function
|
||||
================
|
||||
|
||||
A generic ioctl-like function call back is supported. You will seldom
|
||||
need this. You may even set it to NULL.
|
||||
|
||||
/* No commands defined */
|
||||
int foo_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
need this, and its use is deprecated anyway, so newer design should not
|
||||
use it. Set it to NULL.
|
||||
|
||||
|
||||
Sending and receiving
|
||||
|
|
|
@ -18,6 +18,7 @@ In this document you will find information about:
|
|||
=== 5. Include files
|
||||
--- 5.1 How to include files from the kernel include dir
|
||||
--- 5.2 External modules using an include/ dir
|
||||
--- 5.3 External modules using several directories
|
||||
=== 6. Module installation
|
||||
--- 6.1 INSTALL_MOD_PATH
|
||||
--- 6.2 INSTALL_MOD_DIR
|
||||
|
@ -344,6 +345,45 @@ directory and therefore needs to deal with this in their kbuild file.
|
|||
Note that in the assignment there is no space between -I and the path.
|
||||
This is a kbuild limitation: there must be no space present.
|
||||
|
||||
--- 5.3 External modules using several directories
|
||||
|
||||
If an external module does not follow the usual kernel style but
|
||||
decide to spread files over several directories then kbuild can
|
||||
support this too.
|
||||
|
||||
Consider the following example:
|
||||
|
||||
|
|
||||
+- src/complex_main.c
|
||||
| +- hal/hardwareif.c
|
||||
| +- hal/include/hardwareif.h
|
||||
+- include/complex.h
|
||||
|
||||
To build a single module named complex.ko we then need the following
|
||||
kbuild file:
|
||||
|
||||
Kbuild:
|
||||
obj-m := complex.o
|
||||
complex-y := src/complex_main.o
|
||||
complex-y += src/hal/hardwareif.o
|
||||
|
||||
EXTRA_CFLAGS := -I$(src)/include
|
||||
EXTRA_CFLAGS += -I$(src)src/hal/include
|
||||
|
||||
|
||||
kbuild knows how to handle .o files located in another directory -
|
||||
although this is NOT reccommended practice. The syntax is to specify
|
||||
the directory relative to the directory where the Kbuild file is
|
||||
located.
|
||||
|
||||
To find the .h files we have to explicitly tell kbuild where to look
|
||||
for the .h files. When kbuild executes current directory is always
|
||||
the root of the kernel tree (argument to -C) and therefore we have to
|
||||
tell kbuild how to find the .h files using absolute paths.
|
||||
$(src) will specify the absolute path to the directory where the
|
||||
Kbuild file are located when being build as an external module.
|
||||
Therefore -I$(src)/ is used to point out the directory of the Kbuild
|
||||
file and any additional path are just appended.
|
||||
|
||||
=== 6. Module installation
|
||||
|
||||
|
|
|
@ -910,6 +910,14 @@ running once the system is up.
|
|||
nfsroot= [NFS] nfs root filesystem for disk-less boxes.
|
||||
See Documentation/nfsroot.txt.
|
||||
|
||||
nfs.callback_tcpport=
|
||||
[NFS] set the TCP port on which the NFSv4 callback
|
||||
channel should listen.
|
||||
|
||||
nfs.idmap_cache_timeout=
|
||||
[NFS] set the maximum lifetime for idmapper cache
|
||||
entries.
|
||||
|
||||
nmi_watchdog= [KNL,BUGS=IA-32] Debugging features for SMP kernels
|
||||
|
||||
no387 [BUGS=IA-32] Tells the kernel to use the 387 maths
|
||||
|
|
13
MAINTAINERS
13
MAINTAINERS
|
@ -696,13 +696,6 @@ M: pc300@cyclades.com
|
|||
W: http://www.cyclades.com/
|
||||
S: Supported
|
||||
|
||||
DAC960 RAID CONTROLLER DRIVER
|
||||
P: Dave Olien
|
||||
M dmo@osdl.org
|
||||
W: http://www.osdl.org/archive/dmo/DAC960
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
DAMA SLAVE for AX.25
|
||||
P: Joerg Reuter
|
||||
M: jreuter@yaina.de
|
||||
|
@ -2923,6 +2916,12 @@ W: http://linuxtv.org
|
|||
T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
|
||||
S: Maintained
|
||||
|
||||
VT8231 HARDWARE MONITOR DRIVER
|
||||
P: Roger Lucas
|
||||
M: roger@planbit.co.uk
|
||||
L: lm-sensors@lm-sensors.org
|
||||
S: Maintained
|
||||
|
||||
W1 DALLAS'S 1-WIRE BUS
|
||||
P: Evgeniy Polyakov
|
||||
M: johnpol@2ka.mipt.ru
|
||||
|
|
|
@ -124,17 +124,16 @@ static int max7310_detach_client(struct i2c_client *client)
|
|||
}
|
||||
|
||||
static struct i2c_driver max7310_i2c_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "akita-max7310",
|
||||
.driver = {
|
||||
.name = "akita-max7310",
|
||||
},
|
||||
.id = I2C_DRIVERID_AKITAIOEXP,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = max7310_attach_adapter,
|
||||
.detach_client = max7310_detach_client,
|
||||
};
|
||||
|
||||
static struct i2c_client max7310_template = {
|
||||
name: "akita-max7310",
|
||||
flags: I2C_CLIENT_ALLOW_USE,
|
||||
driver: &max7310_i2c_driver,
|
||||
};
|
||||
|
||||
|
|
1
arch/x86_64/ia32/.gitignore
vendored
1
arch/x86_64/ia32/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
vsyscall*.so
|
|
@ -257,9 +257,10 @@ pcf8583_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||
}
|
||||
|
||||
static struct i2c_driver pcf8583_driver = {
|
||||
.name = "PCF8583",
|
||||
.driver = {
|
||||
.name = "PCF8583",
|
||||
},
|
||||
.id = I2C_DRIVERID_PCF8583,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = pcf8583_probe,
|
||||
.detach_client = pcf8583_detach,
|
||||
.command = pcf8583_command
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* Intel Multimedia Timer device implementation for SGI SN platforms.
|
||||
* Timer device implementation for SGI SN platforms.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (c) 2001-2004 Silicon Graphics, Inc. All rights reserved.
|
||||
* Copyright (c) 2001-2006 Silicon Graphics, Inc. All rights reserved.
|
||||
*
|
||||
* This driver exports an API that should be supportable by any HPET or IA-PC
|
||||
* multimedia timer. The code below is currently specific to the SGI Altix
|
||||
|
@ -45,7 +45,7 @@ MODULE_LICENSE("GPL");
|
|||
/* name of the device, usually in /dev */
|
||||
#define MMTIMER_NAME "mmtimer"
|
||||
#define MMTIMER_DESC "SGI Altix RTC Timer"
|
||||
#define MMTIMER_VERSION "2.0"
|
||||
#define MMTIMER_VERSION "2.1"
|
||||
|
||||
#define RTC_BITS 55 /* 55 bits for this implementation */
|
||||
|
||||
|
@ -227,10 +227,7 @@ typedef struct mmtimer {
|
|||
struct tasklet_struct tasklet;
|
||||
} mmtimer_t;
|
||||
|
||||
/*
|
||||
* Total number of comparators is comparators/node * MAX nodes/running kernel
|
||||
*/
|
||||
static mmtimer_t timers[NUM_COMPARATORS*MAX_COMPACT_NODES];
|
||||
static mmtimer_t ** timers;
|
||||
|
||||
/**
|
||||
* mmtimer_ioctl - ioctl interface for /dev/mmtimer
|
||||
|
@ -441,29 +438,29 @@ static irqreturn_t
|
|||
mmtimer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
int i;
|
||||
mmtimer_t *base = timers + cpu_to_node(smp_processor_id()) *
|
||||
NUM_COMPARATORS;
|
||||
unsigned long expires = 0;
|
||||
int result = IRQ_NONE;
|
||||
unsigned indx = cpu_to_node(smp_processor_id());
|
||||
|
||||
/*
|
||||
* Do this once for each comparison register
|
||||
*/
|
||||
for (i = 0; i < NUM_COMPARATORS; i++) {
|
||||
mmtimer_t *base = timers[indx] + i;
|
||||
/* Make sure this doesn't get reused before tasklet_sched */
|
||||
spin_lock(&base[i].lock);
|
||||
if (base[i].cpu == smp_processor_id()) {
|
||||
if (base[i].timer)
|
||||
expires = base[i].timer->it.mmtimer.expires;
|
||||
spin_lock(&base->lock);
|
||||
if (base->cpu == smp_processor_id()) {
|
||||
if (base->timer)
|
||||
expires = base->timer->it.mmtimer.expires;
|
||||
/* expires test won't work with shared irqs */
|
||||
if ((mmtimer_int_pending(i) > 0) ||
|
||||
(expires && (expires < rtc_time()))) {
|
||||
mmtimer_clr_int_pending(i);
|
||||
tasklet_schedule(&base[i].tasklet);
|
||||
tasklet_schedule(&base->tasklet);
|
||||
result = IRQ_HANDLED;
|
||||
}
|
||||
}
|
||||
spin_unlock(&base[i].lock);
|
||||
spin_unlock(&base->lock);
|
||||
expires = 0;
|
||||
}
|
||||
return result;
|
||||
|
@ -523,7 +520,7 @@ static int sgi_timer_del(struct k_itimer *timr)
|
|||
{
|
||||
int i = timr->it.mmtimer.clock;
|
||||
cnodeid_t nodeid = timr->it.mmtimer.node;
|
||||
mmtimer_t *t = timers + nodeid * NUM_COMPARATORS +i;
|
||||
mmtimer_t *t = timers[nodeid] + i;
|
||||
unsigned long irqflags;
|
||||
|
||||
if (i != TIMER_OFF) {
|
||||
|
@ -609,11 +606,11 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
|
|||
preempt_disable();
|
||||
|
||||
nodeid = cpu_to_node(smp_processor_id());
|
||||
base = timers + nodeid * NUM_COMPARATORS;
|
||||
retry:
|
||||
/* Don't use an allocated timer, or a deleted one that's pending */
|
||||
for(i = 0; i< NUM_COMPARATORS; i++) {
|
||||
if (!base[i].timer && !base[i].tasklet.state) {
|
||||
base = timers[nodeid] + i;
|
||||
if (!base->timer && !base->tasklet.state) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -623,14 +620,14 @@ retry:
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&base[i].lock, irqflags);
|
||||
spin_lock_irqsave(&base->lock, irqflags);
|
||||
|
||||
if (base[i].timer || base[i].tasklet.state != 0) {
|
||||
spin_unlock_irqrestore(&base[i].lock, irqflags);
|
||||
if (base->timer || base->tasklet.state != 0) {
|
||||
spin_unlock_irqrestore(&base->lock, irqflags);
|
||||
goto retry;
|
||||
}
|
||||
base[i].timer = timr;
|
||||
base[i].cpu = smp_processor_id();
|
||||
base->timer = timr;
|
||||
base->cpu = smp_processor_id();
|
||||
|
||||
timr->it.mmtimer.clock = i;
|
||||
timr->it.mmtimer.node = nodeid;
|
||||
|
@ -645,11 +642,11 @@ retry:
|
|||
}
|
||||
} else {
|
||||
timr->it.mmtimer.expires -= period;
|
||||
if (reschedule_periodic_timer(base+i))
|
||||
if (reschedule_periodic_timer(base))
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&base[i].lock, irqflags);
|
||||
spin_unlock_irqrestore(&base->lock, irqflags);
|
||||
|
||||
preempt_enable();
|
||||
|
||||
|
@ -675,6 +672,7 @@ static struct k_clock sgi_clock = {
|
|||
static int __init mmtimer_init(void)
|
||||
{
|
||||
unsigned i;
|
||||
cnodeid_t node, maxn = -1;
|
||||
|
||||
if (!ia64_platform_is("sn2"))
|
||||
return -1;
|
||||
|
@ -691,14 +689,6 @@ static int __init mmtimer_init(void)
|
|||
mmtimer_femtoperiod = ((unsigned long)1E15 + sn_rtc_cycles_per_second /
|
||||
2) / sn_rtc_cycles_per_second;
|
||||
|
||||
for (i=0; i< NUM_COMPARATORS*MAX_COMPACT_NODES; i++) {
|
||||
spin_lock_init(&timers[i].lock);
|
||||
timers[i].timer = NULL;
|
||||
timers[i].cpu = 0;
|
||||
timers[i].i = i % NUM_COMPARATORS;
|
||||
tasklet_init(&timers[i].tasklet, mmtimer_tasklet, (unsigned long) (timers+i));
|
||||
}
|
||||
|
||||
if (request_irq(SGI_MMTIMER_VECTOR, mmtimer_interrupt, SA_PERCPU_IRQ, MMTIMER_NAME, NULL)) {
|
||||
printk(KERN_WARNING "%s: unable to allocate interrupt.",
|
||||
MMTIMER_NAME);
|
||||
|
@ -712,6 +702,40 @@ static int __init mmtimer_init(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Get max numbered node, calculate slots needed */
|
||||
for_each_online_node(node) {
|
||||
maxn = node;
|
||||
}
|
||||
maxn++;
|
||||
|
||||
/* Allocate list of node ptrs to mmtimer_t's */
|
||||
timers = kmalloc(sizeof(mmtimer_t *)*maxn, GFP_KERNEL);
|
||||
if (timers == NULL) {
|
||||
printk(KERN_ERR "%s: failed to allocate memory for device\n",
|
||||
MMTIMER_NAME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocate mmtimer_t's for each online node */
|
||||
for_each_online_node(node) {
|
||||
timers[node] = kmalloc_node(sizeof(mmtimer_t)*NUM_COMPARATORS, GFP_KERNEL, node);
|
||||
if (timers[node] == NULL) {
|
||||
printk(KERN_ERR "%s: failed to allocate memory for device\n",
|
||||
MMTIMER_NAME);
|
||||
return -1;
|
||||
}
|
||||
for (i=0; i< NUM_COMPARATORS; i++) {
|
||||
mmtimer_t * base = timers[node] + i;
|
||||
|
||||
spin_lock_init(&base->lock);
|
||||
base->timer = NULL;
|
||||
base->cpu = 0;
|
||||
base->i = i;
|
||||
tasklet_init(&base->tasklet, mmtimer_tasklet,
|
||||
(unsigned long) (base));
|
||||
}
|
||||
}
|
||||
|
||||
sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second;
|
||||
register_posix_clock(CLOCK_SGI_CYCLE, &sgi_clock);
|
||||
|
||||
|
|
|
@ -350,6 +350,18 @@ config SENSORS_VIA686A
|
|||
This driver can also be built as a module. If so, the module
|
||||
will be called via686a.
|
||||
|
||||
config SENSORS_VT8231
|
||||
tristate "VT8231"
|
||||
depends on HWMON && I2C && PCI && EXPERIMENTAL
|
||||
select HWMON_VID
|
||||
select I2C_ISA
|
||||
help
|
||||
If you say yes here then you get support for the integrated sensors
|
||||
in the VIA VT8231 device.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called vt8231.
|
||||
|
||||
config SENSORS_W83781D
|
||||
tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
|
||||
depends on HWMON && I2C
|
||||
|
|
|
@ -40,6 +40,7 @@ obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
|
|||
obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
|
||||
obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
|
||||
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
|
||||
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
|
||||
obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o
|
||||
obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
|
||||
|
||||
|
|
|
@ -126,10 +126,10 @@ static int read_only;
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver adm1021_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "adm1021",
|
||||
.driver = {
|
||||
.name = "adm1021",
|
||||
},
|
||||
.id = I2C_DRIVERID_ADM1021,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = adm1021_attach_adapter,
|
||||
.detach_client = adm1021_detach_client,
|
||||
};
|
||||
|
|
|
@ -118,10 +118,10 @@ static struct adm1025_data *adm1025_update_device(struct device *dev);
|
|||
*/
|
||||
|
||||
static struct i2c_driver adm1025_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "adm1025",
|
||||
.driver = {
|
||||
.name = "adm1025",
|
||||
},
|
||||
.id = I2C_DRIVERID_ADM1025,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = adm1025_attach_adapter,
|
||||
.detach_client = adm1025_detach_client,
|
||||
};
|
||||
|
@ -287,8 +287,6 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char
|
|||
struct adm1025_data *data = adm1025_update_device(dev);
|
||||
return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
|
||||
}
|
||||
/* in1_ref is deprecated in favour of cpu0_vid, remove after 2005-11-11 */
|
||||
static DEVICE_ATTR(in1_ref, S_IRUGO, show_vid, NULL);
|
||||
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
|
||||
|
||||
static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
|
@ -444,8 +442,6 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||
device_create_file(&new_client->dev, &dev_attr_temp1_max);
|
||||
device_create_file(&new_client->dev, &dev_attr_temp2_max);
|
||||
device_create_file(&new_client->dev, &dev_attr_alarms);
|
||||
/* in1_ref is deprecated, remove after 2005-11-11 */
|
||||
device_create_file(&new_client->dev, &dev_attr_in1_ref);
|
||||
device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
|
||||
device_create_file(&new_client->dev, &dev_attr_vrm);
|
||||
|
||||
|
|
|
@ -308,9 +308,9 @@ static void adm1026_init_client(struct i2c_client *client);
|
|||
|
||||
|
||||
static struct i2c_driver adm1026_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "adm1026",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "adm1026",
|
||||
},
|
||||
.attach_adapter = adm1026_attach_adapter,
|
||||
.detach_client = adm1026_detach_client,
|
||||
};
|
||||
|
@ -1227,8 +1227,6 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, c
|
|||
struct adm1026_data *data = adm1026_update_device(dev);
|
||||
return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm));
|
||||
}
|
||||
/* vid deprecated in favour of cpu0_vid, remove after 2005-11-11 */
|
||||
static DEVICE_ATTR(vid, S_IRUGO, show_vid_reg, NULL);
|
||||
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
|
||||
|
||||
static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
|
@ -1673,8 +1671,6 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address,
|
|||
device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable);
|
||||
device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable);
|
||||
device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable);
|
||||
/* vid deprecated in favour of cpu0_vid, remove after 2005-11-11 */
|
||||
device_create_file(&new_client->dev, &dev_attr_vid);
|
||||
device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
|
||||
device_create_file(&new_client->dev, &dev_attr_vrm);
|
||||
device_create_file(&new_client->dev, &dev_attr_alarms);
|
||||
|
|
|
@ -105,9 +105,9 @@ static struct adm1031_data *adm1031_update_device(struct device *dev);
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver adm1031_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "adm1031",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "adm1031",
|
||||
},
|
||||
.attach_adapter = adm1031_attach_adapter,
|
||||
.detach_client = adm1031_detach_client,
|
||||
};
|
||||
|
|
|
@ -137,10 +137,10 @@ static struct adm9240_data *adm9240_update_device(struct device *dev);
|
|||
|
||||
/* driver data */
|
||||
static struct i2c_driver adm9240_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "adm9240",
|
||||
.driver = {
|
||||
.name = "adm9240",
|
||||
},
|
||||
.id = I2C_DRIVERID_ADM9240,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = adm9240_attach_adapter,
|
||||
.detach_client = adm9240_detach_client,
|
||||
};
|
||||
|
|
|
@ -217,10 +217,10 @@ static struct asb100_data *asb100_update_device(struct device *dev);
|
|||
static void asb100_init_client(struct i2c_client *client);
|
||||
|
||||
static struct i2c_driver asb100_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "asb100",
|
||||
.driver = {
|
||||
.name = "asb100",
|
||||
},
|
||||
.id = I2C_DRIVERID_ASB100,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = asb100_attach_adapter,
|
||||
.detach_client = asb100_detach_client,
|
||||
};
|
||||
|
|
|
@ -50,9 +50,9 @@ static struct atxp1_data * atxp1_update_device(struct device *dev);
|
|||
static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind);
|
||||
|
||||
static struct i2c_driver atxp1_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "atxp1",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "atxp1",
|
||||
},
|
||||
.attach_adapter = atxp1_attach_adapter,
|
||||
.detach_client = atxp1_detach_client,
|
||||
};
|
||||
|
|
|
@ -89,10 +89,10 @@ static struct ds1621_data *ds1621_update_client(struct device *dev);
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver ds1621_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ds1621",
|
||||
.driver = {
|
||||
.name = "ds1621",
|
||||
},
|
||||
.id = I2C_DRIVERID_DS1621,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = ds1621_attach_adapter,
|
||||
.detach_client = ds1621_detach_client,
|
||||
};
|
||||
|
|
|
@ -118,10 +118,10 @@ static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value);
|
|||
*/
|
||||
|
||||
static struct i2c_driver fscher_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "fscher",
|
||||
.driver = {
|
||||
.name = "fscher",
|
||||
},
|
||||
.id = I2C_DRIVERID_FSCHER,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = fscher_attach_adapter,
|
||||
.detach_client = fscher_detach_client,
|
||||
};
|
||||
|
|
|
@ -100,10 +100,10 @@ static void reset_fan_alarm(struct i2c_client *client, int nr);
|
|||
* Driver data (common to all clients)
|
||||
*/
|
||||
static struct i2c_driver fscpos_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "fscpos",
|
||||
.driver = {
|
||||
.name = "fscpos",
|
||||
},
|
||||
.id = I2C_DRIVERID_FSCPOS,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = fscpos_attach_adapter,
|
||||
.detach_client = fscpos_detach_client,
|
||||
};
|
||||
|
|
|
@ -151,10 +151,10 @@ static struct gl518_data *gl518_update_device(struct device *dev);
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver gl518_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "gl518sm",
|
||||
.driver = {
|
||||
.name = "gl518sm",
|
||||
},
|
||||
.id = I2C_DRIVERID_GL518,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = gl518_attach_adapter,
|
||||
.detach_client = gl518_detach_client,
|
||||
};
|
||||
|
|
|
@ -109,10 +109,10 @@ static struct gl520_data *gl520_update_device(struct device *dev);
|
|||
|
||||
/* Driver data */
|
||||
static struct i2c_driver gl520_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "gl520sm",
|
||||
.driver = {
|
||||
.name = "gl520sm",
|
||||
},
|
||||
.id = I2C_DRIVERID_GL520,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = gl520_attach_adapter,
|
||||
.detach_client = gl520_detach_client,
|
||||
};
|
||||
|
|
|
@ -49,20 +49,22 @@
|
|||
. . . .
|
||||
11110 = 0.800 V
|
||||
11111 = 0.000 V (off)
|
||||
|
||||
The 17 specification is in fact Intel Mobile Voltage Positioning -
|
||||
(IMVP-II). You can find more information in the datasheet of Max1718
|
||||
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452
|
||||
|
||||
*/
|
||||
|
||||
/* 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_from_reg(int val, u8 vrm)
|
||||
{
|
||||
int vid;
|
||||
|
||||
switch(vrm) {
|
||||
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case 100: /* VRD 10.0 */
|
||||
if((val & 0x1f) == 0x1f)
|
||||
return 0;
|
||||
|
@ -91,10 +93,16 @@ int vid_from_reg(int val, int vrm)
|
|||
case 84: /* VRM 8.4 */
|
||||
val &= 0x0f;
|
||||
/* fall through */
|
||||
default: /* VRM 8.2 */
|
||||
case 82: /* VRM 8.2 */
|
||||
return(val == 0x1f ? 0 :
|
||||
val & 0x10 ? 5100 - (val) * 100 :
|
||||
2050 - (val) * 50);
|
||||
case 17: /* Intel IMVP-II */
|
||||
return(val & 0x10 ? 975 - (val & 0xF) * 25 :
|
||||
1750 - val * 50);
|
||||
default: /* report 0 for unknown */
|
||||
printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,30 +116,36 @@ struct vrm_model {
|
|||
u8 vendor;
|
||||
u8 eff_family;
|
||||
u8 eff_model;
|
||||
int vrm_type;
|
||||
u8 eff_stepping;
|
||||
u8 vrm_type;
|
||||
};
|
||||
|
||||
#define ANY 0xFF
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
|
||||
/* the stepping parameter is highest acceptable stepping for current line */
|
||||
|
||||
static struct vrm_model vrm_models[] = {
|
||||
{X86_VENDOR_AMD, 0x6, ANY, 90}, /* Athlon Duron etc */
|
||||
{X86_VENDOR_AMD, 0xF, ANY, 24}, /* Athlon 64, Opteron */
|
||||
{X86_VENDOR_INTEL, 0x6, 0x9, 85}, /* 0.13um too */
|
||||
{X86_VENDOR_INTEL, 0x6, 0xB, 85}, /* Tualatin */
|
||||
{X86_VENDOR_INTEL, 0x6, ANY, 82}, /* any P6 */
|
||||
{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, 0x4, 100}, /* P4 Prescott */
|
||||
{X86_VENDOR_INTEL, 0x10,ANY, 0}, /* Itanium 2 */
|
||||
{X86_VENDOR_UNKNOWN, ANY, ANY, 0} /* stop here */
|
||||
{X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */
|
||||
{X86_VENDOR_AMD, 0xF, ANY, ANY, 24}, /* Athlon 64, Opteron and above VRM 24 */
|
||||
{X86_VENDOR_INTEL, 0x6, 0x9, ANY, 85}, /* 0.13um too */
|
||||
{X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */
|
||||
{X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */
|
||||
{X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */
|
||||
{X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */
|
||||
{X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */
|
||||
{X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */
|
||||
{X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */
|
||||
{X86_VENDOR_INTEL, 0x10, ANY, ANY, 0}, /* Itanium 2 */
|
||||
{X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */
|
||||
{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */
|
||||
{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */
|
||||
{X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M */
|
||||
{X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */
|
||||
};
|
||||
|
||||
static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor)
|
||||
static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
@ -139,7 +153,8 @@ static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor)
|
|||
if (vrm_models[i].vendor==vendor)
|
||||
if ((vrm_models[i].eff_family==eff_family)
|
||||
&& ((vrm_models[i].eff_model==eff_model) ||
|
||||
(vrm_models[i].eff_model==ANY)))
|
||||
(vrm_models[i].eff_model==ANY)) &&
|
||||
(eff_stepping <= vrm_models[i].eff_stepping))
|
||||
return vrm_models[i].vrm_type;
|
||||
i++;
|
||||
}
|
||||
|
@ -147,12 +162,11 @@ static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int vid_which_vrm(void)
|
||||
u8 vid_which_vrm(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = cpu_data;
|
||||
u32 eax;
|
||||
u8 eff_family, eff_model;
|
||||
int vrm_ret;
|
||||
u8 eff_family, eff_model, eff_stepping, vrm_ret;
|
||||
|
||||
if (c->x86 < 6) /* Any CPU with family lower than 6 */
|
||||
return 0; /* doesn't have VID and/or CPUID */
|
||||
|
@ -160,20 +174,21 @@ int vid_which_vrm(void)
|
|||
eax = cpuid_eax(1);
|
||||
eff_family = ((eax & 0x00000F00)>>8);
|
||||
eff_model = ((eax & 0x000000F0)>>4);
|
||||
eff_stepping = eax & 0xF;
|
||||
if (eff_family == 0xF) { /* use extended model & family */
|
||||
eff_family += ((eax & 0x00F00000)>>20);
|
||||
eff_model += ((eax & 0x000F0000)>>16)<<4;
|
||||
}
|
||||
vrm_ret = find_vrm(eff_family,eff_model,c->x86_vendor);
|
||||
vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor);
|
||||
if (vrm_ret == 0)
|
||||
printk(KERN_INFO "hwmon-vid: Unknown VRM version of your "
|
||||
"x86 CPU\n");
|
||||
return vrm_ret;
|
||||
}
|
||||
|
||||
/* and now something completely different for the non-x86 world */
|
||||
/* and now for something completely different for the non-x86 world */
|
||||
#else
|
||||
int vid_which_vrm(void)
|
||||
u8 vid_which_vrm(void)
|
||||
{
|
||||
printk(KERN_INFO "hwmon-vid: Unknown VRM version of your CPU\n");
|
||||
return 0;
|
||||
|
|
|
@ -213,7 +213,7 @@ struct it87_data {
|
|||
u8 sensor; /* Register value */
|
||||
u8 fan_div[3]; /* Register encoding, shifted right */
|
||||
u8 vid; /* Register encoding, combined */
|
||||
int vrm;
|
||||
u8 vrm;
|
||||
u32 alarms; /* Register encoding, combined */
|
||||
u8 fan_main_ctrl; /* Register value */
|
||||
u8 manual_pwm_ctl[3]; /* manual PWM value set by user */
|
||||
|
@ -234,17 +234,18 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data);
|
|||
|
||||
|
||||
static struct i2c_driver it87_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "it87",
|
||||
.driver = {
|
||||
.name = "it87",
|
||||
},
|
||||
.id = I2C_DRIVERID_IT87,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = it87_attach_adapter,
|
||||
.detach_client = it87_detach_client,
|
||||
};
|
||||
|
||||
static struct i2c_driver it87_isa_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "it87-isa",
|
||||
.driver = {
|
||||
.name = "it87-isa",
|
||||
},
|
||||
.attach_adapter = it87_isa_attach_adapter,
|
||||
.detach_client = it87_detach_client,
|
||||
};
|
||||
|
@ -668,7 +669,7 @@ static ssize_t
|
|||
show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct it87_data *data = it87_update_device(dev);
|
||||
return sprintf(buf, "%ld\n", (long) data->vrm);
|
||||
return sprintf(buf, "%u\n", data->vrm);
|
||||
}
|
||||
static ssize_t
|
||||
store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
||||
|
@ -761,7 +762,8 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||
|
||||
/* Reserve the ISA region */
|
||||
if (is_isa)
|
||||
if (!request_region(address, IT87_EXTENT, it87_isa_driver.name))
|
||||
if (!request_region(address, IT87_EXTENT,
|
||||
it87_isa_driver.driver.name))
|
||||
goto ERROR0;
|
||||
|
||||
/* For now, we presume we have a valid client. We create the
|
||||
|
|
|
@ -139,9 +139,9 @@ static void lm63_init_client(struct i2c_client *client);
|
|||
*/
|
||||
|
||||
static struct i2c_driver lm63_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm63",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "lm63",
|
||||
},
|
||||
.attach_adapter = lm63_attach_adapter,
|
||||
.detach_client = lm63_detach_client,
|
||||
};
|
||||
|
|
|
@ -66,10 +66,10 @@ static struct lm75_data *lm75_update_device(struct device *dev);
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver lm75_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm75",
|
||||
.driver = {
|
||||
.name = "lm75",
|
||||
},
|
||||
.id = I2C_DRIVERID_LM75,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = lm75_attach_adapter,
|
||||
.detach_client = lm75_detach_client,
|
||||
};
|
||||
|
|
|
@ -74,9 +74,9 @@ static struct lm77_data *lm77_update_device(struct device *dev);
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver lm77_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm77",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "lm77",
|
||||
},
|
||||
.attach_adapter = lm77_attach_adapter,
|
||||
.detach_client = lm77_detach_client,
|
||||
};
|
||||
|
|
|
@ -164,17 +164,18 @@ static void lm78_init_client(struct i2c_client *client);
|
|||
|
||||
|
||||
static struct i2c_driver lm78_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm78",
|
||||
.driver = {
|
||||
.name = "lm78",
|
||||
},
|
||||
.id = I2C_DRIVERID_LM78,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = lm78_attach_adapter,
|
||||
.detach_client = lm78_detach_client,
|
||||
};
|
||||
|
||||
static struct i2c_driver lm78_isa_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm78-isa",
|
||||
.driver = {
|
||||
.name = "lm78-isa",
|
||||
},
|
||||
.attach_adapter = lm78_isa_attach_adapter,
|
||||
.detach_client = lm78_detach_client,
|
||||
};
|
||||
|
@ -497,7 +498,7 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||
/* Reserve the ISA region */
|
||||
if (is_isa)
|
||||
if (!request_region(address, LM78_EXTENT,
|
||||
lm78_isa_driver.name)) {
|
||||
lm78_isa_driver.driver.name)) {
|
||||
err = -EBUSY;
|
||||
goto ERROR0;
|
||||
}
|
||||
|
|
|
@ -143,10 +143,10 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value);
|
|||
*/
|
||||
|
||||
static struct i2c_driver lm80_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm80",
|
||||
.driver = {
|
||||
.name = "lm80",
|
||||
},
|
||||
.id = I2C_DRIVERID_LM80,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = lm80_attach_adapter,
|
||||
.detach_client = lm80_detach_client,
|
||||
};
|
||||
|
|
|
@ -124,10 +124,10 @@ static struct lm83_data *lm83_update_device(struct device *dev);
|
|||
*/
|
||||
|
||||
static struct i2c_driver lm83_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm83",
|
||||
.driver = {
|
||||
.name = "lm83",
|
||||
},
|
||||
.id = I2C_DRIVERID_LM83,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = lm83_attach_adapter,
|
||||
.detach_client = lm83_detach_client,
|
||||
};
|
||||
|
|
|
@ -380,10 +380,10 @@ static void lm85_init_client(struct i2c_client *client);
|
|||
|
||||
|
||||
static struct i2c_driver lm85_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm85",
|
||||
.driver = {
|
||||
.name = "lm85",
|
||||
},
|
||||
.id = I2C_DRIVERID_LM85,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = lm85_attach_adapter,
|
||||
.detach_client = lm85_detach_client,
|
||||
};
|
||||
|
@ -443,7 +443,17 @@ show_fan_offset(4);
|
|||
static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct lm85_data *data = lm85_update_device(dev);
|
||||
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
|
||||
int vid;
|
||||
|
||||
if (data->type == adt7463 && (data->vid & 0x80)) {
|
||||
/* 6-pin VID (VRM 10) */
|
||||
vid = vid_from_reg(data->vid & 0x3f, data->vrm);
|
||||
} else {
|
||||
/* 5-pin VID (VRM 9) */
|
||||
vid = vid_from_reg(data->vid & 0x1f, data->vrm);
|
||||
}
|
||||
|
||||
return sprintf(buf, "%d\n", vid);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
|
||||
|
@ -1176,17 +1186,14 @@ static int lm85_detect(struct i2c_adapter *adapter, int address,
|
|||
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_in3_input);
|
||||
device_create_file(&new_client->dev, &dev_attr_in4_input);
|
||||
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_in2_min);
|
||||
device_create_file(&new_client->dev, &dev_attr_in3_min);
|
||||
device_create_file(&new_client->dev, &dev_attr_in4_min);
|
||||
device_create_file(&new_client->dev, &dev_attr_in0_max);
|
||||
device_create_file(&new_client->dev, &dev_attr_in1_max);
|
||||
device_create_file(&new_client->dev, &dev_attr_in2_max);
|
||||
device_create_file(&new_client->dev, &dev_attr_in3_max);
|
||||
device_create_file(&new_client->dev, &dev_attr_in4_max);
|
||||
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_temp3_input);
|
||||
|
@ -1224,6 +1231,15 @@ static int lm85_detect(struct i2c_adapter *adapter, int address,
|
|||
device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_crit);
|
||||
device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_crit);
|
||||
|
||||
/* The ADT7463 has an optional VRM 10 mode where pin 21 is used
|
||||
as a sixth digital VID input rather than an analog input. */
|
||||
data->vid = lm85_read_value(new_client, LM85_REG_VID);
|
||||
if (!(kind == adt7463 && (data->vid & 0x80))) {
|
||||
device_create_file(&new_client->dev, &dev_attr_in4_input);
|
||||
device_create_file(&new_client->dev, &dev_attr_in4_min);
|
||||
device_create_file(&new_client->dev, &dev_attr_in4_max);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
/* Error out and cleanup code */
|
||||
|
@ -1382,11 +1398,18 @@ static struct lm85_data *lm85_update_device(struct device *dev)
|
|||
irrelevant. So it is left in 4*/
|
||||
data->adc_scale = (data->type == emc6d102 ) ? 16 : 4;
|
||||
|
||||
for (i = 0; i <= 4; ++i) {
|
||||
data->vid = lm85_read_value(client, LM85_REG_VID);
|
||||
|
||||
for (i = 0; i <= 3; ++i) {
|
||||
data->in[i] =
|
||||
lm85_read_value(client, LM85_REG_IN(i));
|
||||
}
|
||||
|
||||
if (!(data->type == adt7463 && (data->vid & 0x80))) {
|
||||
data->in[4] = lm85_read_value(client,
|
||||
LM85_REG_IN(4));
|
||||
}
|
||||
|
||||
for (i = 0; i <= 3; ++i) {
|
||||
data->fan[i] =
|
||||
lm85_read_value(client, LM85_REG_FAN(i));
|
||||
|
@ -1450,13 +1473,20 @@ static struct lm85_data *lm85_update_device(struct device *dev)
|
|||
/* Things that don't change often */
|
||||
dev_dbg(&client->dev, "Reading config values\n");
|
||||
|
||||
for (i = 0; i <= 4; ++i) {
|
||||
for (i = 0; i <= 3; ++i) {
|
||||
data->in_min[i] =
|
||||
lm85_read_value(client, LM85_REG_IN_MIN(i));
|
||||
data->in_max[i] =
|
||||
lm85_read_value(client, LM85_REG_IN_MAX(i));
|
||||
}
|
||||
|
||||
if (!(data->type == adt7463 && (data->vid & 0x80))) {
|
||||
data->in_min[4] = lm85_read_value(client,
|
||||
LM85_REG_IN_MIN(4));
|
||||
data->in_max[4] = lm85_read_value(client,
|
||||
LM85_REG_IN_MAX(4));
|
||||
}
|
||||
|
||||
if ( data->type == emc6d100 ) {
|
||||
for (i = 5; i <= 7; ++i) {
|
||||
data->in_min[i] =
|
||||
|
@ -1478,8 +1508,6 @@ static struct lm85_data *lm85_update_device(struct device *dev)
|
|||
lm85_read_value(client, LM85_REG_TEMP_MAX(i));
|
||||
}
|
||||
|
||||
data->vid = lm85_read_value(client, LM85_REG_VID);
|
||||
|
||||
for (i = 0; i <= 2; ++i) {
|
||||
int val ;
|
||||
data->autofan[i].config =
|
||||
|
|
|
@ -161,10 +161,10 @@ static struct lm87_data *lm87_update_device(struct device *dev);
|
|||
*/
|
||||
|
||||
static struct i2c_driver lm87_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm87",
|
||||
.driver = {
|
||||
.name = "lm87",
|
||||
},
|
||||
.id = I2C_DRIVERID_LM87,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = lm87_attach_adapter,
|
||||
.detach_client = lm87_detach_client,
|
||||
};
|
||||
|
|
|
@ -186,10 +186,10 @@ static struct lm90_data *lm90_update_device(struct device *dev);
|
|||
*/
|
||||
|
||||
static struct i2c_driver lm90_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm90",
|
||||
.driver = {
|
||||
.name = "lm90",
|
||||
},
|
||||
.id = I2C_DRIVERID_LM90,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = lm90_attach_adapter,
|
||||
.detach_client = lm90_detach_client,
|
||||
};
|
||||
|
|
|
@ -410,10 +410,10 @@ static int lm92_detach_client(struct i2c_client *client)
|
|||
*/
|
||||
|
||||
static struct i2c_driver lm92_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lm92",
|
||||
.driver = {
|
||||
.name = "lm92",
|
||||
},
|
||||
.id = I2C_DRIVERID_LM92,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = lm92_attach_adapter,
|
||||
.detach_client = lm92_detach_client,
|
||||
};
|
||||
|
|
|
@ -90,9 +90,9 @@ static struct max1619_data *max1619_update_device(struct device *dev);
|
|||
*/
|
||||
|
||||
static struct i2c_driver max1619_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "max1619",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "max1619",
|
||||
},
|
||||
.attach_adapter = max1619_attach_adapter,
|
||||
.detach_client = max1619_detach_client,
|
||||
};
|
||||
|
|
|
@ -236,8 +236,9 @@ static struct pc87360_data *pc87360_update_device(struct device *dev);
|
|||
*/
|
||||
|
||||
static struct i2c_driver pc87360_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pc87360",
|
||||
.driver = {
|
||||
.name = "pc87360",
|
||||
},
|
||||
.attach_adapter = pc87360_detect,
|
||||
.detach_client = pc87360_detach_client,
|
||||
};
|
||||
|
@ -798,7 +799,7 @@ static int pc87360_detect(struct i2c_adapter *adapter)
|
|||
for (i = 0; i < 3; i++) {
|
||||
if (((data->address[i] = extra_isa[i]))
|
||||
&& !request_region(extra_isa[i], PC87360_EXTENT,
|
||||
pc87360_driver.name)) {
|
||||
pc87360_driver.driver.name)) {
|
||||
dev_err(&new_client->dev, "Region 0x%x-0x%x already "
|
||||
"in use!\n", extra_isa[i],
|
||||
extra_isa[i]+PC87360_EXTENT-1);
|
||||
|
|
|
@ -198,8 +198,9 @@ static struct sis5595_data *sis5595_update_device(struct device *dev);
|
|||
static void sis5595_init_client(struct i2c_client *client);
|
||||
|
||||
static struct i2c_driver sis5595_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "sis5595",
|
||||
.driver = {
|
||||
.name = "sis5595",
|
||||
},
|
||||
.attach_adapter = sis5595_detect,
|
||||
.detach_client = sis5595_detach_client,
|
||||
};
|
||||
|
@ -484,7 +485,8 @@ static int sis5595_detect(struct i2c_adapter *adapter)
|
|||
if (force_addr)
|
||||
address = force_addr & ~(SIS5595_EXTENT - 1);
|
||||
/* Reserve the ISA region */
|
||||
if (!request_region(address, SIS5595_EXTENT, sis5595_driver.name)) {
|
||||
if (!request_region(address, SIS5595_EXTENT,
|
||||
sis5595_driver.driver.name)) {
|
||||
err = -EBUSY;
|
||||
goto exit;
|
||||
}
|
||||
|
|
|
@ -226,8 +226,9 @@ static int smsc47b397_detach_client(struct i2c_client *client)
|
|||
static int smsc47b397_detect(struct i2c_adapter *adapter);
|
||||
|
||||
static struct i2c_driver smsc47b397_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "smsc47b397",
|
||||
.driver = {
|
||||
.name = "smsc47b397",
|
||||
},
|
||||
.attach_adapter = smsc47b397_detect,
|
||||
.detach_client = smsc47b397_detach_client,
|
||||
};
|
||||
|
@ -238,7 +239,8 @@ static int smsc47b397_detect(struct i2c_adapter *adapter)
|
|||
struct smsc47b397_data *data;
|
||||
int err = 0;
|
||||
|
||||
if (!request_region(address, SMSC_EXTENT, smsc47b397_driver.name)) {
|
||||
if (!request_region(address, SMSC_EXTENT,
|
||||
smsc47b397_driver.driver.name)) {
|
||||
dev_err(&adapter->dev, "Region 0x%x already in use!\n",
|
||||
address);
|
||||
return -EBUSY;
|
||||
|
|
|
@ -126,8 +126,9 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
|
|||
|
||||
|
||||
static struct i2c_driver smsc47m1_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "smsc47m1",
|
||||
.driver = {
|
||||
.name = "smsc47m1",
|
||||
},
|
||||
.attach_adapter = smsc47m1_detect,
|
||||
.detach_client = smsc47m1_detach_client,
|
||||
};
|
||||
|
@ -394,7 +395,7 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
|
|||
int err = 0;
|
||||
int fan1, fan2, pwm1, pwm2;
|
||||
|
||||
if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) {
|
||||
if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.driver.name)) {
|
||||
dev_err(&adapter->dev, "Region 0x%x already in use!\n", address);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
|
|
@ -572,8 +572,9 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
|
|||
/* The driver. I choose to use type i2c_driver, as at is identical to both
|
||||
smbus_driver and isa_driver, and clients could be of either kind */
|
||||
static struct i2c_driver via686a_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "via686a",
|
||||
.driver = {
|
||||
.name = "via686a",
|
||||
},
|
||||
.attach_adapter = via686a_detect,
|
||||
.detach_client = via686a_detach_client,
|
||||
};
|
||||
|
@ -615,7 +616,8 @@ static int via686a_detect(struct i2c_adapter *adapter)
|
|||
}
|
||||
|
||||
/* Reserve the ISA region */
|
||||
if (!request_region(address, VIA686A_EXTENT, via686a_driver.name)) {
|
||||
if (!request_region(address, VIA686A_EXTENT,
|
||||
via686a_driver.driver.name)) {
|
||||
dev_err(&adapter->dev, "region 0x%x already in use!\n",
|
||||
address);
|
||||
return -ENODEV;
|
||||
|
|
862
drivers/hwmon/vt8231.c
Normal file
862
drivers/hwmon/vt8231.c
Normal file
|
@ -0,0 +1,862 @@
|
|||
/*
|
||||
vt8231.c - Part of lm_sensors, Linux kernel modules
|
||||
for hardware monitoring
|
||||
|
||||
Copyright (c) 2005 Roger Lucas <roger@planbit.co.uk>
|
||||
Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
|
||||
Aaron M. Marsh <amarsh@sdf.lonestar.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Supports VIA VT8231 South Bridge embedded sensors
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-isa.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/hwmon-vid.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
static int force_addr;
|
||||
module_param(force_addr, int, 0);
|
||||
MODULE_PARM_DESC(force_addr, "Initialize the base address of the sensors");
|
||||
|
||||
/* Device address
|
||||
Note that we can't determine the ISA address until we have initialized
|
||||
our module */
|
||||
static unsigned short isa_address;
|
||||
|
||||
#define VT8231_EXTENT 0x80
|
||||
#define VT8231_BASE_REG 0x70
|
||||
#define VT8231_ENABLE_REG 0x74
|
||||
|
||||
/* The VT8231 registers
|
||||
|
||||
The reset value for the input channel configuration is used (Reg 0x4A=0x07)
|
||||
which sets the selected inputs marked with '*' below if multiple options are
|
||||
possible:
|
||||
|
||||
Voltage Mode Temperature Mode
|
||||
Sensor Linux Id Linux Id VIA Id
|
||||
-------- -------- -------- ------
|
||||
CPU Diode N/A temp1 0
|
||||
UIC1 in0 temp2 * 1
|
||||
UIC2 in1 * temp3 2
|
||||
UIC3 in2 * temp4 3
|
||||
UIC4 in3 * temp5 4
|
||||
UIC5 in4 * temp6 5
|
||||
3.3V in5 N/A
|
||||
|
||||
Note that the BIOS may set the configuration register to a different value
|
||||
to match the motherboard configuration.
|
||||
*/
|
||||
|
||||
/* fans numbered 0-1 */
|
||||
#define VT8231_REG_FAN_MIN(nr) (0x3b + (nr))
|
||||
#define VT8231_REG_FAN(nr) (0x29 + (nr))
|
||||
|
||||
/* Voltage inputs numbered 0-5 */
|
||||
|
||||
static const u8 regvolt[] = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26 };
|
||||
static const u8 regvoltmax[] = { 0x3d, 0x2b, 0x2d, 0x2f, 0x31, 0x33 };
|
||||
static const u8 regvoltmin[] = { 0x3e, 0x2c, 0x2e, 0x30, 0x32, 0x34 };
|
||||
|
||||
/* Temperatures are numbered 1-6 according to the Linux kernel specification.
|
||||
**
|
||||
** In the VIA datasheet, however, the temperatures are numbered from zero.
|
||||
** Since it is important that this driver can easily be compared to the VIA
|
||||
** datasheet, we will use the VIA numbering within this driver and map the
|
||||
** kernel sysfs device name to the VIA number in the sysfs callback.
|
||||
*/
|
||||
|
||||
#define VT8231_REG_TEMP_LOW01 0x49
|
||||
#define VT8231_REG_TEMP_LOW25 0x4d
|
||||
|
||||
static const u8 regtemp[] = { 0x1f, 0x21, 0x22, 0x23, 0x24, 0x25 };
|
||||
static const u8 regtempmax[] = { 0x39, 0x3d, 0x2b, 0x2d, 0x2f, 0x31 };
|
||||
static const u8 regtempmin[] = { 0x3a, 0x3e, 0x2c, 0x2e, 0x30, 0x32 };
|
||||
|
||||
#define TEMP_FROM_REG(reg) (((253 * 4 - (reg)) * 550 + 105) / 210)
|
||||
#define TEMP_MAXMIN_FROM_REG(reg) (((253 - (reg)) * 2200 + 105) / 210)
|
||||
#define TEMP_MAXMIN_TO_REG(val) (253 - ((val) * 210 + 1100) / 2200)
|
||||
|
||||
#define VT8231_REG_CONFIG 0x40
|
||||
#define VT8231_REG_ALARM1 0x41
|
||||
#define VT8231_REG_ALARM2 0x42
|
||||
#define VT8231_REG_FANDIV 0x47
|
||||
#define VT8231_REG_UCH_CONFIG 0x4a
|
||||
#define VT8231_REG_TEMP1_CONFIG 0x4b
|
||||
#define VT8231_REG_TEMP2_CONFIG 0x4c
|
||||
|
||||
/* temps 0-5 as numbered in VIA datasheet - see later for mapping to Linux
|
||||
** numbering
|
||||
*/
|
||||
#define ISTEMP(i, ch_config) ((i) == 0 ? 1 : \
|
||||
((ch_config) >> ((i)+1)) & 0x01)
|
||||
/* voltages 0-5 */
|
||||
#define ISVOLT(i, ch_config) ((i) == 5 ? 1 : \
|
||||
!(((ch_config) >> ((i)+2)) & 0x01))
|
||||
|
||||
#define DIV_FROM_REG(val) (1 << (val))
|
||||
|
||||
/* NB The values returned here are NOT temperatures. The calibration curves
|
||||
** for the thermistor curves are board-specific and must go in the
|
||||
** sensors.conf file. Temperature sensors are actually ten bits, but the
|
||||
** VIA datasheet only considers the 8 MSBs obtained from the regtemp[]
|
||||
** register. The temperature value returned should have a magnitude of 3,
|
||||
** so we use the VIA scaling as the "true" scaling and use the remaining 2
|
||||
** LSBs as fractional precision.
|
||||
**
|
||||
** All the on-chip hardware temperature comparisons for the alarms are only
|
||||
** 8-bits wide, and compare against the 8 MSBs of the temperature. The bits
|
||||
** in the registers VT8231_REG_TEMP_LOW01 and VT8231_REG_TEMP_LOW25 are
|
||||
** ignored.
|
||||
*/
|
||||
|
||||
/******** FAN RPM CONVERSIONS ********
|
||||
** This chip saturates back at 0, not at 255 like many the other chips.
|
||||
** So, 0 means 0 RPM
|
||||
*/
|
||||
static inline u8 FAN_TO_REG(long rpm, int div)
|
||||
{
|
||||
if (rpm == 0)
|
||||
return 0;
|
||||
return SENSORS_LIMIT(1310720 / (rpm * div), 1, 255);
|
||||
}
|
||||
|
||||
#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 1310720 / ((val) * (div)))
|
||||
|
||||
struct vt8231_data {
|
||||
struct i2c_client client;
|
||||
struct semaphore update_lock;
|
||||
struct class_device *class_dev;
|
||||
char valid; /* !=0 if following fields are valid */
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
|
||||
u8 in[6]; /* Register value */
|
||||
u8 in_max[6]; /* Register value */
|
||||
u8 in_min[6]; /* Register value */
|
||||
u16 temp[6]; /* Register value 10 bit, right aligned */
|
||||
u8 temp_max[6]; /* Register value */
|
||||
u8 temp_min[6]; /* Register value */
|
||||
u8 fan[2]; /* Register value */
|
||||
u8 fan_min[2]; /* Register value */
|
||||
u8 fan_div[2]; /* Register encoding, shifted right */
|
||||
u16 alarms; /* Register encoding */
|
||||
u8 uch_config;
|
||||
};
|
||||
|
||||
static struct pci_dev *s_bridge;
|
||||
static int vt8231_detect(struct i2c_adapter *adapter);
|
||||
static int vt8231_detach_client(struct i2c_client *client);
|
||||
static struct vt8231_data *vt8231_update_device(struct device *dev);
|
||||
static void vt8231_init_client(struct i2c_client *client);
|
||||
|
||||
static inline int vt8231_read_value(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
return inb_p(client->addr + reg);
|
||||
}
|
||||
|
||||
static inline void vt8231_write_value(struct i2c_client *client, u8 reg,
|
||||
u8 value)
|
||||
{
|
||||
outb_p(value, client->addr + reg);
|
||||
}
|
||||
|
||||
/* following are the sysfs callback functions */
|
||||
static ssize_t show_in(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", ((data->in[nr] - 3) * 10000) / 958);
|
||||
}
|
||||
|
||||
static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", ((data->in_min[nr] - 3) * 10000) / 958);
|
||||
}
|
||||
|
||||
static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", (((data->in_max[nr] - 3) * 10000) / 958));
|
||||
}
|
||||
|
||||
static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
unsigned long val = simple_strtoul(buf, NULL, 10);
|
||||
|
||||
down(&data->update_lock);
|
||||
data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255);
|
||||
vt8231_write_value(client, regvoltmin[nr], data->in_min[nr]);
|
||||
up(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
unsigned long val = simple_strtoul(buf, NULL, 10);
|
||||
|
||||
down(&data->update_lock);
|
||||
data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255);
|
||||
vt8231_write_value(client, regvoltmax[nr], data->in_max[nr]);
|
||||
up(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Special case for input 5 as this has 3.3V scaling built into the chip */
|
||||
static ssize_t show_in5(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n",
|
||||
(((data->in[5] - 3) * 10000 * 54) / (958 * 34)));
|
||||
}
|
||||
|
||||
static ssize_t show_in5_min(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n",
|
||||
(((data->in_min[5] - 3) * 10000 * 54) / (958 * 34)));
|
||||
}
|
||||
|
||||
static ssize_t show_in5_max(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n",
|
||||
(((data->in_max[5] - 3) * 10000 * 54) / (958 * 34)));
|
||||
}
|
||||
|
||||
static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
unsigned long val = simple_strtoul(buf, NULL, 10);
|
||||
|
||||
down(&data->update_lock);
|
||||
data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3,
|
||||
0, 255);
|
||||
vt8231_write_value(client, regvoltmin[5], data->in_min[5]);
|
||||
up(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
unsigned long val = simple_strtoul(buf, NULL, 10);
|
||||
|
||||
down(&data->update_lock);
|
||||
data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3,
|
||||
0, 255);
|
||||
vt8231_write_value(client, regvoltmax[5], data->in_max[5]);
|
||||
up(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
#define define_voltage_sysfs(offset) \
|
||||
static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
|
||||
show_in, NULL, offset); \
|
||||
static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
|
||||
show_in_min, set_in_min, offset); \
|
||||
static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
|
||||
show_in_max, set_in_max, offset)
|
||||
|
||||
define_voltage_sysfs(0);
|
||||
define_voltage_sysfs(1);
|
||||
define_voltage_sysfs(2);
|
||||
define_voltage_sysfs(3);
|
||||
define_voltage_sysfs(4);
|
||||
|
||||
static DEVICE_ATTR(in5_input, S_IRUGO, show_in5, NULL);
|
||||
static DEVICE_ATTR(in5_min, S_IRUGO | S_IWUSR, show_in5_min, set_in5_min);
|
||||
static DEVICE_ATTR(in5_max, S_IRUGO | S_IWUSR, show_in5_max, set_in5_max);
|
||||
|
||||
/* Temperatures */
|
||||
static ssize_t show_temp0(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
return sprintf(buf, "%d\n", data->temp[0] * 250);
|
||||
}
|
||||
|
||||
static ssize_t show_temp0_max(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
return sprintf(buf, "%d\n", data->temp_max[0] * 1000);
|
||||
}
|
||||
|
||||
static ssize_t show_temp0_min(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
return sprintf(buf, "%d\n", data->temp_min[0] * 1000);
|
||||
}
|
||||
|
||||
static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
int val = simple_strtol(buf, NULL, 10);
|
||||
|
||||
down(&data->update_lock);
|
||||
data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255);
|
||||
vt8231_write_value(client, regtempmax[0], data->temp_max[0]);
|
||||
up(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
int val = simple_strtol(buf, NULL, 10);
|
||||
|
||||
down(&data->update_lock);
|
||||
data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255);
|
||||
vt8231_write_value(client, regtempmin[0], data->temp_min[0]);
|
||||
up(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
|
||||
}
|
||||
|
||||
static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
return sprintf(buf, "%d\n", TEMP_MAXMIN_FROM_REG(data->temp_max[nr]));
|
||||
}
|
||||
|
||||
static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
return sprintf(buf, "%d\n", TEMP_MAXMIN_FROM_REG(data->temp_min[nr]));
|
||||
}
|
||||
|
||||
static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
int val = simple_strtol(buf, NULL, 10);
|
||||
|
||||
down(&data->update_lock);
|
||||
data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255);
|
||||
vt8231_write_value(client, regtempmax[nr], data->temp_max[nr]);
|
||||
up(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
int val = simple_strtol(buf, NULL, 10);
|
||||
|
||||
down(&data->update_lock);
|
||||
data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255);
|
||||
vt8231_write_value(client, regtempmin[nr], data->temp_min[nr]);
|
||||
up(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Note that these map the Linux temperature sensor numbering (1-6) to the VIA
|
||||
** temperature sensor numbering (0-5)
|
||||
*/
|
||||
#define define_temperature_sysfs(offset) \
|
||||
static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
|
||||
show_temp, NULL, offset - 1); \
|
||||
static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
|
||||
show_temp_max, set_temp_max, offset - 1); \
|
||||
static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
|
||||
show_temp_min, set_temp_min, offset - 1)
|
||||
|
||||
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp0, NULL);
|
||||
static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp0_max, set_temp0_max);
|
||||
static DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, show_temp0_min, set_temp0_min);
|
||||
|
||||
define_temperature_sysfs(2);
|
||||
define_temperature_sysfs(3);
|
||||
define_temperature_sysfs(4);
|
||||
define_temperature_sysfs(5);
|
||||
define_temperature_sysfs(6);
|
||||
|
||||
#define CFG_INFO_TEMP(id) { &sensor_dev_attr_temp##id##_input.dev_attr, \
|
||||
&sensor_dev_attr_temp##id##_min.dev_attr, \
|
||||
&sensor_dev_attr_temp##id##_max.dev_attr }
|
||||
#define CFG_INFO_VOLT(id) { &sensor_dev_attr_in##id##_input.dev_attr, \
|
||||
&sensor_dev_attr_in##id##_min.dev_attr, \
|
||||
&sensor_dev_attr_in##id##_max.dev_attr }
|
||||
|
||||
struct str_device_attr_table {
|
||||
struct device_attribute *input;
|
||||
struct device_attribute *min;
|
||||
struct device_attribute *max;
|
||||
};
|
||||
|
||||
static struct str_device_attr_table cfg_info_temp[] = {
|
||||
{ &dev_attr_temp1_input, &dev_attr_temp1_min, &dev_attr_temp1_max },
|
||||
CFG_INFO_TEMP(2),
|
||||
CFG_INFO_TEMP(3),
|
||||
CFG_INFO_TEMP(4),
|
||||
CFG_INFO_TEMP(5),
|
||||
CFG_INFO_TEMP(6)
|
||||
};
|
||||
|
||||
static struct str_device_attr_table cfg_info_volt[] = {
|
||||
CFG_INFO_VOLT(0),
|
||||
CFG_INFO_VOLT(1),
|
||||
CFG_INFO_VOLT(2),
|
||||
CFG_INFO_VOLT(3),
|
||||
CFG_INFO_VOLT(4),
|
||||
{ &dev_attr_in5_input, &dev_attr_in5_min, &dev_attr_in5_max }
|
||||
};
|
||||
|
||||
/* Fans */
|
||||
static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
|
||||
DIV_FROM_REG(data->fan_div[nr])));
|
||||
}
|
||||
|
||||
static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
|
||||
DIV_FROM_REG(data->fan_div[nr])));
|
||||
}
|
||||
|
||||
static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
|
||||
}
|
||||
|
||||
static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
int nr = sensor_attr->index;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
int val = simple_strtoul(buf, NULL, 10);
|
||||
|
||||
down(&data->update_lock);
|
||||
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
|
||||
vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]);
|
||||
up(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
||||
unsigned long val = simple_strtoul(buf, NULL, 10);
|
||||
int nr = sensor_attr->index;
|
||||
int old = vt8231_read_value(client, VT8231_REG_FANDIV);
|
||||
long min = FAN_FROM_REG(data->fan_min[nr],
|
||||
DIV_FROM_REG(data->fan_div[nr]));
|
||||
|
||||
down(&data->update_lock);
|
||||
switch (val) {
|
||||
case 1: data->fan_div[nr] = 0; break;
|
||||
case 2: data->fan_div[nr] = 1; break;
|
||||
case 4: data->fan_div[nr] = 2; break;
|
||||
case 8: data->fan_div[nr] = 3; break;
|
||||
default:
|
||||
dev_err(&client->dev, "fan_div value %ld not supported."
|
||||
"Choose one of 1, 2, 4 or 8!\n", val);
|
||||
up(&data->update_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Correct the fan minimum speed */
|
||||
data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
|
||||
vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]);
|
||||
|
||||
old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
|
||||
vt8231_write_value(client, VT8231_REG_FANDIV, old);
|
||||
up(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
#define define_fan_sysfs(offset) \
|
||||
static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
|
||||
show_fan, NULL, offset - 1); \
|
||||
static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
|
||||
show_fan_div, set_fan_div, offset - 1); \
|
||||
static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
|
||||
show_fan_min, set_fan_min, offset - 1)
|
||||
|
||||
define_fan_sysfs(1);
|
||||
define_fan_sysfs(2);
|
||||
|
||||
/* Alarms */
|
||||
static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct vt8231_data *data = vt8231_update_device(dev);
|
||||
return sprintf(buf, "%d\n", data->alarms);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
|
||||
|
||||
static struct i2c_driver vt8231_driver = {
|
||||
.driver = {
|
||||
.name = "vt8231",
|
||||
},
|
||||
.attach_adapter = vt8231_detect,
|
||||
.detach_client = vt8231_detach_client,
|
||||
};
|
||||
|
||||
static struct pci_device_id vt8231_pci_ids[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
|
||||
|
||||
static int __devinit vt8231_pci_probe(struct pci_dev *dev,
|
||||
const struct pci_device_id *id);
|
||||
|
||||
static struct pci_driver vt8231_pci_driver = {
|
||||
.name = "vt8231",
|
||||
.id_table = vt8231_pci_ids,
|
||||
.probe = vt8231_pci_probe,
|
||||
};
|
||||
|
||||
int vt8231_detect(struct i2c_adapter *adapter)
|
||||
{
|
||||
struct i2c_client *client;
|
||||
struct vt8231_data *data;
|
||||
int err = 0, i;
|
||||
u16 val;
|
||||
|
||||
/* 8231 requires multiple of 256 */
|
||||
if (force_addr) {
|
||||
isa_address = force_addr & 0xFF00;
|
||||
dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n",
|
||||
isa_address);
|
||||
if (PCIBIOS_SUCCESSFUL != pci_write_config_word(s_bridge,
|
||||
VT8231_BASE_REG, isa_address))
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (PCIBIOS_SUCCESSFUL !=
|
||||
pci_read_config_word(s_bridge, VT8231_ENABLE_REG, &val))
|
||||
return -ENODEV;
|
||||
|
||||
if (!(val & 0x0001)) {
|
||||
dev_warn(&adapter->dev, "enabling sensors\n");
|
||||
if (PCIBIOS_SUCCESSFUL !=
|
||||
pci_write_config_word(s_bridge, VT8231_ENABLE_REG,
|
||||
val | 0x0001))
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Reserve the ISA region */
|
||||
if (!request_region(isa_address, VT8231_EXTENT,
|
||||
vt8231_pci_driver.name)) {
|
||||
dev_err(&adapter->dev, "region 0x%x already in use!\n",
|
||||
isa_address);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!(data = kzalloc(sizeof(struct vt8231_data), GFP_KERNEL))) {
|
||||
err = -ENOMEM;
|
||||
goto exit_release;
|
||||
}
|
||||
|
||||
client = &data->client;
|
||||
i2c_set_clientdata(client, data);
|
||||
client->addr = isa_address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &vt8231_driver;
|
||||
client->dev.parent = &adapter->dev;
|
||||
|
||||
/* Fill in the remaining client fields and put into the global list */
|
||||
strlcpy(client->name, "vt8231", I2C_NAME_SIZE);
|
||||
|
||||
init_MUTEX(&data->update_lock);
|
||||
|
||||
/* Tell the I2C layer a new client has arrived */
|
||||
if ((err = i2c_attach_client(client)))
|
||||
goto exit_free;
|
||||
|
||||
vt8231_init_client(client);
|
||||
|
||||
/* Register sysfs hooks */
|
||||
data->class_dev = hwmon_device_register(&client->dev);
|
||||
if (IS_ERR(data->class_dev)) {
|
||||
err = PTR_ERR(data->class_dev);
|
||||
goto exit_detach;
|
||||
}
|
||||
|
||||
/* Must update device information to find out the config field */
|
||||
data->uch_config = vt8231_read_value(client, VT8231_REG_UCH_CONFIG);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cfg_info_temp); i++) {
|
||||
if (ISTEMP(i, data->uch_config)) {
|
||||
device_create_file(&client->dev,
|
||||
cfg_info_temp[i].input);
|
||||
device_create_file(&client->dev, cfg_info_temp[i].max);
|
||||
device_create_file(&client->dev, cfg_info_temp[i].min);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cfg_info_volt); i++) {
|
||||
if (ISVOLT(i, data->uch_config)) {
|
||||
device_create_file(&client->dev,
|
||||
cfg_info_volt[i].input);
|
||||
device_create_file(&client->dev, cfg_info_volt[i].max);
|
||||
device_create_file(&client->dev, cfg_info_volt[i].min);
|
||||
}
|
||||
}
|
||||
|
||||
device_create_file(&client->dev, &sensor_dev_attr_fan1_input.dev_attr);
|
||||
device_create_file(&client->dev, &sensor_dev_attr_fan2_input.dev_attr);
|
||||
device_create_file(&client->dev, &sensor_dev_attr_fan1_min.dev_attr);
|
||||
device_create_file(&client->dev, &sensor_dev_attr_fan2_min.dev_attr);
|
||||
device_create_file(&client->dev, &sensor_dev_attr_fan1_div.dev_attr);
|
||||
device_create_file(&client->dev, &sensor_dev_attr_fan2_div.dev_attr);
|
||||
|
||||
device_create_file(&client->dev, &dev_attr_alarms);
|
||||
return 0;
|
||||
|
||||
exit_detach:
|
||||
i2c_detach_client(client);
|
||||
exit_free:
|
||||
kfree(data);
|
||||
exit_release:
|
||||
release_region(isa_address, VT8231_EXTENT);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int vt8231_detach_client(struct i2c_client *client)
|
||||
{
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
int err;
|
||||
|
||||
hwmon_device_unregister(data->class_dev);
|
||||
|
||||
if ((err = i2c_detach_client(client))) {
|
||||
return err;
|
||||
}
|
||||
|
||||
release_region(client->addr, VT8231_EXTENT);
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vt8231_init_client(struct i2c_client *client)
|
||||
{
|
||||
vt8231_write_value(client, VT8231_REG_TEMP1_CONFIG, 0);
|
||||
vt8231_write_value(client, VT8231_REG_TEMP2_CONFIG, 0);
|
||||
}
|
||||
|
||||
static struct vt8231_data *vt8231_update_device(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct vt8231_data *data = i2c_get_clientdata(client);
|
||||
int i;
|
||||
u16 low;
|
||||
|
||||
down(&data->update_lock);
|
||||
|
||||
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|
||||
|| !data->valid) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (ISVOLT(i, data->uch_config)) {
|
||||
data->in[i] = vt8231_read_value(client,
|
||||
regvolt[i]);
|
||||
data->in_min[i] = vt8231_read_value(client,
|
||||
regvoltmin[i]);
|
||||
data->in_max[i] = vt8231_read_value(client,
|
||||
regvoltmax[i]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
data->fan[i] = vt8231_read_value(client,
|
||||
VT8231_REG_FAN(i));
|
||||
data->fan_min[i] = vt8231_read_value(client,
|
||||
VT8231_REG_FAN_MIN(i));
|
||||
}
|
||||
|
||||
low = vt8231_read_value(client, VT8231_REG_TEMP_LOW01);
|
||||
low = (low >> 6) | ((low & 0x30) >> 2)
|
||||
| (vt8231_read_value(client, VT8231_REG_TEMP_LOW25) << 4);
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (ISTEMP(i, data->uch_config)) {
|
||||
data->temp[i] = (vt8231_read_value(client,
|
||||
regtemp[i]) << 2)
|
||||
| ((low >> (2 * i)) & 0x03);
|
||||
data->temp_max[i] = vt8231_read_value(client,
|
||||
regtempmax[i]);
|
||||
data->temp_min[i] = vt8231_read_value(client,
|
||||
regtempmin[i]);
|
||||
}
|
||||
}
|
||||
|
||||
i = vt8231_read_value(client, VT8231_REG_FANDIV);
|
||||
data->fan_div[0] = (i >> 4) & 0x03;
|
||||
data->fan_div[1] = i >> 6;
|
||||
data->alarms = vt8231_read_value(client, VT8231_REG_ALARM1) |
|
||||
(vt8231_read_value(client, VT8231_REG_ALARM2) << 8);
|
||||
|
||||
/* Set alarm flags correctly */
|
||||
if (!data->fan[0] && data->fan_min[0]) {
|
||||
data->alarms |= 0x40;
|
||||
} else if (data->fan[0] && !data->fan_min[0]) {
|
||||
data->alarms &= ~0x40;
|
||||
}
|
||||
|
||||
if (!data->fan[1] && data->fan_min[1]) {
|
||||
data->alarms |= 0x80;
|
||||
} else if (data->fan[1] && !data->fan_min[1]) {
|
||||
data->alarms &= ~0x80;
|
||||
}
|
||||
|
||||
data->last_updated = jiffies;
|
||||
data->valid = 1;
|
||||
}
|
||||
|
||||
up(&data->update_lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static int __devinit vt8231_pci_probe(struct pci_dev *dev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
u16 val;
|
||||
|
||||
if (PCIBIOS_SUCCESSFUL != pci_read_config_word(dev, VT8231_BASE_REG,
|
||||
&val))
|
||||
return -ENODEV;
|
||||
|
||||
isa_address = val & ~(VT8231_EXTENT - 1);
|
||||
if (isa_address == 0 && force_addr == 0) {
|
||||
dev_err(&dev->dev, "base address not set -\
|
||||
upgrade BIOS or use force_addr=0xaddr\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
s_bridge = pci_dev_get(dev);
|
||||
|
||||
if (i2c_isa_add_driver(&vt8231_driver)) {
|
||||
pci_dev_put(s_bridge);
|
||||
s_bridge = NULL;
|
||||
}
|
||||
|
||||
/* Always return failure here. This is to allow other drivers to bind
|
||||
* to this pci device. We don't really want to have control over the
|
||||
* pci device, we only wanted to read as few register values from it.
|
||||
*/
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int __init sm_vt8231_init(void)
|
||||
{
|
||||
return pci_module_init(&vt8231_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit sm_vt8231_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&vt8231_pci_driver);
|
||||
if (s_bridge != NULL) {
|
||||
i2c_isa_del_driver(&vt8231_driver);
|
||||
pci_dev_put(s_bridge);
|
||||
s_bridge = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Roger Lucas <roger@planbit.co.uk>");
|
||||
MODULE_DESCRIPTION("VT8231 sensors");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(sm_vt8231_init);
|
||||
module_exit(sm_vt8231_exit);
|
|
@ -676,7 +676,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
|
|||
int i, err = 0;
|
||||
|
||||
if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
|
||||
w83627ehf_driver.name)) {
|
||||
w83627ehf_driver.driver.name)) {
|
||||
err = -EBUSY;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -785,8 +785,9 @@ static int w83627ehf_detach_client(struct i2c_client *client)
|
|||
}
|
||||
|
||||
static struct i2c_driver w83627ehf_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "w83627ehf",
|
||||
.driver = {
|
||||
.name = "w83627ehf",
|
||||
},
|
||||
.attach_adapter = w83627ehf_detect,
|
||||
.detach_client = w83627ehf_detach_client,
|
||||
};
|
||||
|
|
|
@ -332,8 +332,9 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev);
|
|||
static void w83627hf_init_client(struct i2c_client *client);
|
||||
|
||||
static struct i2c_driver w83627hf_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "w83627hf",
|
||||
.driver = {
|
||||
.name = "w83627hf",
|
||||
},
|
||||
.attach_adapter = w83627hf_detect,
|
||||
.detach_client = w83627hf_detach_client,
|
||||
};
|
||||
|
@ -1009,7 +1010,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
|
|||
address = force_addr & WINB_ALIGNMENT;
|
||||
|
||||
if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE,
|
||||
w83627hf_driver.name)) {
|
||||
w83627hf_driver.driver.name)) {
|
||||
err = -EBUSY;
|
||||
goto ERROR0;
|
||||
}
|
||||
|
@ -1122,11 +1123,10 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
|
|||
if (kind != w83697hf)
|
||||
device_create_file_temp(new_client, 3);
|
||||
|
||||
if (kind != w83697hf)
|
||||
if (kind != w83697hf && data->vid != 0xff) {
|
||||
device_create_file_vid(new_client);
|
||||
|
||||
if (kind != w83697hf)
|
||||
device_create_file_vrm(new_client);
|
||||
}
|
||||
|
||||
device_create_file_fan_div(new_client, 1);
|
||||
device_create_file_fan_div(new_client, 2);
|
||||
|
@ -1232,7 +1232,7 @@ static int w83627thf_read_gpio5(struct i2c_client *client)
|
|||
|
||||
/* Make sure the pins are configured for input
|
||||
There must be at least five (VRM 9), and possibly 6 (VRM 10) */
|
||||
sel = superio_inb(W83627THF_GPIO5_IOSR);
|
||||
sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f;
|
||||
if ((sel & 0x1f) != 0x1f) {
|
||||
dev_dbg(&client->dev, "GPIO5 not configured for VID "
|
||||
"function\n");
|
||||
|
@ -1323,19 +1323,18 @@ static void w83627hf_init_client(struct i2c_client *client)
|
|||
int hi = w83627hf_read_value(client, W83781D_REG_CHIPID);
|
||||
data->vid = (lo & 0x0f) | ((hi & 0x01) << 4);
|
||||
} else if (w83627thf == data->type) {
|
||||
data->vid = w83627thf_read_gpio5(client) & 0x3f;
|
||||
data->vid = w83627thf_read_gpio5(client);
|
||||
}
|
||||
|
||||
/* Read VRM & OVT Config only once */
|
||||
if (w83627thf == data->type || w83637hf == data->type) {
|
||||
data->vrm_ovt =
|
||||
w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG);
|
||||
data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82;
|
||||
} else {
|
||||
/* Convert VID to voltage based on default VRM */
|
||||
data->vrm = vid_which_vrm();
|
||||
}
|
||||
|
||||
/* Convert VID to voltage based on VRM */
|
||||
data->vrm = vid_which_vrm();
|
||||
|
||||
tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
|
||||
for (i = 1; i <= 3; i++) {
|
||||
if (!(tmp & BIT_SCFG1[i - 1])) {
|
||||
|
|
|
@ -269,17 +269,18 @@ static struct w83781d_data *w83781d_update_device(struct device *dev);
|
|||
static void w83781d_init_client(struct i2c_client *client);
|
||||
|
||||
static struct i2c_driver w83781d_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "w83781d",
|
||||
.driver = {
|
||||
.name = "w83781d",
|
||||
},
|
||||
.id = I2C_DRIVERID_W83781D,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = w83781d_attach_adapter,
|
||||
.detach_client = w83781d_detach_client,
|
||||
};
|
||||
|
||||
static struct i2c_driver w83781d_isa_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "w83781d-isa",
|
||||
.driver = {
|
||||
.name = "w83781d-isa",
|
||||
},
|
||||
.attach_adapter = w83781d_isa_attach_adapter,
|
||||
.detach_client = w83781d_detach_client,
|
||||
};
|
||||
|
@ -1012,7 +1013,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||
|
||||
if (is_isa)
|
||||
if (!request_region(address, W83781D_EXTENT,
|
||||
w83781d_isa_driver.name)) {
|
||||
w83781d_isa_driver.driver.name)) {
|
||||
dev_dbg(&adapter->dev, "Request of region "
|
||||
"0x%x-0x%x for w83781d failed\n", address,
|
||||
address + W83781D_EXTENT - 1);
|
||||
|
|
|
@ -269,7 +269,6 @@ DIV_TO_REG(long val)
|
|||
struct w83792d_data {
|
||||
struct i2c_client client;
|
||||
struct class_device *class_dev;
|
||||
struct semaphore lock;
|
||||
enum chips type;
|
||||
|
||||
struct semaphore update_lock;
|
||||
|
@ -282,7 +281,7 @@ struct w83792d_data {
|
|||
u8 in[9]; /* Register value */
|
||||
u8 in_max[9]; /* Register value */
|
||||
u8 in_min[9]; /* Register value */
|
||||
u8 low_bits[2]; /* Additional resolution to voltage in0-6 */
|
||||
u16 low_bits; /* Additional resolution to voltage in6-0 */
|
||||
u8 fan[7]; /* Register value */
|
||||
u8 fan_min[7]; /* Register value */
|
||||
u8 temp1[3]; /* current, over, thyst */
|
||||
|
@ -317,45 +316,17 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev);
|
|||
static void w83792d_init_client(struct i2c_client *client);
|
||||
|
||||
static struct i2c_driver w83792d_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "w83792d",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "w83792d",
|
||||
},
|
||||
.attach_adapter = w83792d_attach_adapter,
|
||||
.detach_client = w83792d_detach_client,
|
||||
};
|
||||
|
||||
static long in_count_from_reg(int nr, struct w83792d_data *data)
|
||||
static inline long in_count_from_reg(int nr, struct w83792d_data *data)
|
||||
{
|
||||
u16 vol_count = data->in[nr];
|
||||
u16 low_bits = 0;
|
||||
vol_count = (vol_count << 2);
|
||||
switch (nr)
|
||||
{
|
||||
case 0: /* vin0 */
|
||||
low_bits = (data->low_bits[0]) & 0x03;
|
||||
break;
|
||||
case 1: /* vin1 */
|
||||
low_bits = ((data->low_bits[0]) & 0x0c) >> 2;
|
||||
break;
|
||||
case 2: /* vin2 */
|
||||
low_bits = ((data->low_bits[0]) & 0x30) >> 4;
|
||||
break;
|
||||
case 3: /* vin3 */
|
||||
low_bits = ((data->low_bits[0]) & 0xc0) >> 6;
|
||||
break;
|
||||
case 4: /* vin4 */
|
||||
low_bits = (data->low_bits[1]) & 0x03;
|
||||
break;
|
||||
case 5: /* vin5 */
|
||||
low_bits = ((data->low_bits[1]) & 0x0c) >> 2;
|
||||
break;
|
||||
case 6: /* vin6 */
|
||||
low_bits = ((data->low_bits[1]) & 0x30) >> 4;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
vol_count = vol_count | low_bits;
|
||||
return vol_count;
|
||||
/* in7 and in8 do not have low bits, but the formula still works */
|
||||
return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03));
|
||||
}
|
||||
|
||||
/* following are the sysfs callback functions */
|
||||
|
@ -1192,7 +1163,6 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||
new_client = &data->client;
|
||||
i2c_set_clientdata(new_client, data);
|
||||
new_client->addr = address;
|
||||
init_MUTEX(&data->lock);
|
||||
new_client->adapter = adapter;
|
||||
new_client->driver = &w83792d_driver;
|
||||
new_client->flags = 0;
|
||||
|
@ -1243,7 +1213,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||
goto ERROR1;
|
||||
}
|
||||
val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID);
|
||||
if (val1 == 0x7a && address >= 0x2c) {
|
||||
if (val1 == 0x7a) {
|
||||
kind = w83792d;
|
||||
} else {
|
||||
if (kind == 0)
|
||||
|
@ -1416,26 +1386,17 @@ w83792d_detach_client(struct i2c_client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* The SMBus locks itself, usually, but nothing may access the Winbond between
|
||||
bank switches. ISA access must always be locked explicitly!
|
||||
We ignore the W83792D BUSY flag at this moment - it could lead to deadlocks,
|
||||
would slow down the W83792D access and should not be necessary.
|
||||
There are some ugly typecasts here, but the good news is - they should
|
||||
nowhere else be necessary! */
|
||||
static int
|
||||
w83792d_read_value(struct i2c_client *client, u8 reg)
|
||||
/* The SMBus locks itself. The Winbond W83792D chip has a bank register,
|
||||
but the driver only accesses registers in bank 0, so we don't have
|
||||
to switch banks and lock access between switches. */
|
||||
static int w83792d_read_value(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
int res=0;
|
||||
res = i2c_smbus_read_byte_data(client, reg);
|
||||
|
||||
return res;
|
||||
return i2c_smbus_read_byte_data(client, reg);
|
||||
}
|
||||
|
||||
static int
|
||||
w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
|
||||
static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
|
||||
{
|
||||
i2c_smbus_write_byte_data(client, reg, value);
|
||||
return 0;
|
||||
return i2c_smbus_write_byte_data(client, reg, value);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1492,10 +1453,10 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
|
|||
data->in_min[i] = w83792d_read_value(client,
|
||||
W83792D_REG_IN_MIN[i]);
|
||||
}
|
||||
data->low_bits[0] = w83792d_read_value(client,
|
||||
W83792D_REG_LOW_BITS1);
|
||||
data->low_bits[1] = w83792d_read_value(client,
|
||||
W83792D_REG_LOW_BITS2);
|
||||
data->low_bits = w83792d_read_value(client,
|
||||
W83792D_REG_LOW_BITS1) +
|
||||
(w83792d_read_value(client,
|
||||
W83792D_REG_LOW_BITS2) << 8);
|
||||
for (i = 0; i < 7; i++) {
|
||||
/* Update the Fan measured value and limits */
|
||||
data->fan[i] = w83792d_read_value(client,
|
||||
|
@ -1506,7 +1467,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
|
|||
pwm_array_tmp[i] = w83792d_read_value(client,
|
||||
W83792D_REG_PWM[i]);
|
||||
data->pwm[i] = pwm_array_tmp[i] & 0x0f;
|
||||
data->pwm_mode[i] = (pwm_array_tmp[i] >> 7) & 0x01;
|
||||
data->pwm_mode[i] = pwm_array_tmp[i] >> 7;
|
||||
}
|
||||
|
||||
reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG);
|
||||
|
@ -1607,8 +1568,8 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev)
|
|||
dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]);
|
||||
dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]);
|
||||
}
|
||||
dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits[0]);
|
||||
dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits[1]);
|
||||
dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits & 0xff);
|
||||
dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits >> 8);
|
||||
dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n");
|
||||
for (i=0; i<7; i++) {
|
||||
dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]);
|
||||
|
|
|
@ -92,10 +92,10 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev);
|
|||
*/
|
||||
|
||||
static struct i2c_driver w83l785ts_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "w83l785ts",
|
||||
.driver = {
|
||||
.name = "w83l785ts",
|
||||
},
|
||||
.id = I2C_DRIVERID_W83L785TS,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = w83l785ts_attach_adapter,
|
||||
.detach_client = w83l785ts_detach_client,
|
||||
};
|
||||
|
|
|
@ -468,8 +468,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (hwpec)
|
||||
outb_p(1, SMBAUXCTL); /* enable hardware PEC */
|
||||
outb_p(hwpec, SMBAUXCTL); /* enable/disable hardware PEC */
|
||||
|
||||
if(block)
|
||||
ret = i801_block_transaction(data, read_write, size, hwpec);
|
||||
|
@ -478,9 +477,6 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
|
|||
ret = i801_transaction();
|
||||
}
|
||||
|
||||
if (hwpec)
|
||||
outb_p(0, SMBAUXCTL); /* disable hardware PEC */
|
||||
|
||||
if(block)
|
||||
return ret;
|
||||
if(ret)
|
||||
|
|
|
@ -725,6 +725,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
|
|||
strcpy(adap->name, "IBM IIC");
|
||||
i2c_set_adapdata(adap, dev);
|
||||
adap->id = I2C_HW_OCP;
|
||||
adap->class = I2C_CLASS_HWMON;
|
||||
adap->algo = &iic_algo;
|
||||
adap->client_register = NULL;
|
||||
adap->client_unregister = NULL;
|
||||
|
|
|
@ -92,15 +92,13 @@ int i2c_isa_add_driver(struct i2c_driver *driver)
|
|||
int res;
|
||||
|
||||
/* Add the driver to the list of i2c drivers in the driver core */
|
||||
driver->driver.name = driver->name;
|
||||
driver->driver.owner = driver->owner;
|
||||
driver->driver.bus = &i2c_bus_type;
|
||||
driver->driver.probe = i2c_isa_device_probe;
|
||||
driver->driver.remove = i2c_isa_device_remove;
|
||||
res = driver_register(&driver->driver);
|
||||
if (res)
|
||||
return res;
|
||||
dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->name);
|
||||
dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->driver.name);
|
||||
|
||||
/* Now look for clients */
|
||||
driver->attach_adapter(&isa_adapter);
|
||||
|
@ -124,14 +122,14 @@ int i2c_isa_del_driver(struct i2c_driver *driver)
|
|||
if ((res = driver->detach_client(client))) {
|
||||
dev_err(&isa_adapter.dev, "Failed, driver "
|
||||
"%s not unregistered!\n",
|
||||
driver->name);
|
||||
driver->driver.name);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the driver off the core list */
|
||||
driver_unregister(&driver->driver);
|
||||
dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->name);
|
||||
dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->driver.name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -176,7 +174,7 @@ static void __exit i2c_isa_exit(void)
|
|||
list_for_each_safe(item, _n, &isa_adapter.clients) {
|
||||
client = list_entry(item, struct i2c_client, list);
|
||||
dev_err(&isa_adapter.dev, "Driver %s still has an active "
|
||||
"ISA client at 0x%x\n", client->driver->name,
|
||||
"ISA client at 0x%x\n", client->driver->driver.name,
|
||||
client->addr);
|
||||
}
|
||||
if (client != NULL)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* drivers/i2c/busses/i2c-mv64xxx.c
|
||||
*
|
||||
* Driver for the i2c controller on the Marvell line of host bridges for MIPS
|
||||
* and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0).
|
||||
*
|
||||
|
@ -65,7 +63,6 @@ enum {
|
|||
MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
|
||||
MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK,
|
||||
MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA,
|
||||
MV64XXX_I2C_STATE_ABORTING,
|
||||
};
|
||||
|
||||
/* Driver actions */
|
||||
|
@ -85,6 +82,7 @@ struct mv64xxx_i2c_data {
|
|||
int irq;
|
||||
u32 state;
|
||||
u32 action;
|
||||
u32 aborting;
|
||||
u32 cntl_bits;
|
||||
void __iomem *reg_base;
|
||||
u32 reg_base_p;
|
||||
|
@ -122,12 +120,6 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
|
|||
return;
|
||||
}
|
||||
|
||||
if (drv_data->state == MV64XXX_I2C_STATE_ABORTING) {
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
|
||||
drv_data->state = MV64XXX_I2C_STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* The status from the ctlr [mostly] tells us what to do next */
|
||||
switch (status) {
|
||||
/* Start condition interrupt */
|
||||
|
@ -148,14 +140,16 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
|
|||
/* FALLTHRU */
|
||||
case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */
|
||||
case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */
|
||||
if (drv_data->bytes_left > 0) {
|
||||
if ((drv_data->bytes_left == 0)
|
||||
|| (drv_data->aborting
|
||||
&& (drv_data->byte_posn != 0))) {
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
|
||||
drv_data->state = MV64XXX_I2C_STATE_IDLE;
|
||||
} else {
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
|
||||
drv_data->state =
|
||||
MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK;
|
||||
drv_data->bytes_left--;
|
||||
} else {
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
|
||||
drv_data->state = MV64XXX_I2C_STATE_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -184,7 +178,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
|
|||
}
|
||||
drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA;
|
||||
|
||||
if (drv_data->bytes_left == 1)
|
||||
if ((drv_data->bytes_left == 1) || drv_data->aborting)
|
||||
drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK;
|
||||
break;
|
||||
|
||||
|
@ -320,6 +314,7 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
|
|||
drv_data->msg = msg;
|
||||
drv_data->byte_posn = 0;
|
||||
drv_data->bytes_left = msg->len;
|
||||
drv_data->aborting = 0;
|
||||
drv_data->rc = 0;
|
||||
drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
|
||||
MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
|
||||
|
@ -359,17 +354,19 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
|
|||
}
|
||||
|
||||
if (abort && drv_data->block) {
|
||||
drv_data->state = MV64XXX_I2C_STATE_ABORTING;
|
||||
drv_data->aborting = 1;
|
||||
spin_unlock_irqrestore(&drv_data->lock, flags);
|
||||
|
||||
time_left = wait_event_timeout(drv_data->waitq,
|
||||
!drv_data->block,
|
||||
msecs_to_jiffies(drv_data->adapter.timeout));
|
||||
|
||||
if (time_left <= 0) {
|
||||
if ((time_left <= 0) && drv_data->block) {
|
||||
drv_data->state = MV64XXX_I2C_STATE_IDLE;
|
||||
dev_err(&drv_data->adapter.dev,
|
||||
"mv64xxx: I2C bus locked\n");
|
||||
"mv64xxx: I2C bus locked, block: %d, "
|
||||
"time_left: %d\n", drv_data->block,
|
||||
(int)time_left);
|
||||
}
|
||||
} else
|
||||
spin_unlock_irqrestore(&drv_data->lock, flags);
|
||||
|
@ -510,7 +507,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
|
|||
goto exit_kfree;
|
||||
}
|
||||
|
||||
strncpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
|
||||
strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
|
||||
I2C_NAME_SIZE);
|
||||
|
||||
init_waitqueue_head(&drv_data->waitq);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
nForce3 Pro150 MCP 00D4
|
||||
nForce3 250Gb MCP 00E4
|
||||
nForce4 MCP 0052
|
||||
nForce4 MCP-04 0034
|
||||
|
||||
This driver supports the 2 SMBuses that are included in the MCP of the
|
||||
nForce2/3/4 chipsets.
|
||||
|
@ -257,6 +258,7 @@ static struct pci_device_id nforce2_ids[] = {
|
|||
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
|
|
@ -80,6 +80,14 @@ static struct adapter_parm adapter_parm[] = {
|
|||
.setscl = { 0x01, DATA, 1 },
|
||||
.getsda = { 0x10, STAT, 1 },
|
||||
},
|
||||
/* type 6: Barco LPT->DVI (K5800236) adapter */
|
||||
{
|
||||
.setsda = { 0x02, DATA, 1 },
|
||||
.setscl = { 0x01, DATA, 1 },
|
||||
.getsda = { 0x20, STAT, 0 },
|
||||
.getscl = { 0x40, STAT, 0 },
|
||||
.init = { 0xfc, DATA, 0 },
|
||||
},
|
||||
};
|
||||
|
||||
static int type;
|
||||
|
@ -91,4 +99,6 @@ MODULE_PARM_DESC(type,
|
|||
" 2 = Velleman K8000 adapter\n"
|
||||
" 3 = ELV adapter\n"
|
||||
" 4 = ADM1032 evaluation board\n"
|
||||
" 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n");
|
||||
" 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n"
|
||||
" 6 = Barco LPT->DVI (K5800236) adapter\n"
|
||||
);
|
||||
|
|
|
@ -52,9 +52,9 @@ static int ds1337_command(struct i2c_client *client, unsigned int cmd,
|
|||
* Driver data (common to all clients)
|
||||
*/
|
||||
static struct i2c_driver ds1337_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ds1337",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "ds1337",
|
||||
},
|
||||
.attach_adapter = ds1337_attach_adapter,
|
||||
.detach_client = ds1337_detach_client,
|
||||
.command = ds1337_command,
|
||||
|
@ -337,13 +337,38 @@ exit:
|
|||
|
||||
static void ds1337_init_client(struct i2c_client *client)
|
||||
{
|
||||
s32 val;
|
||||
u8 status, control;
|
||||
|
||||
/* Ensure that device is set in 24-hour mode */
|
||||
val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
|
||||
if ((val >= 0) && (val & (1 << 6)))
|
||||
i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
|
||||
val & 0x3f);
|
||||
/* On some boards, the RTC isn't configured by boot firmware.
|
||||
* Handle that case by starting/configuring the RTC now.
|
||||
*/
|
||||
status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);
|
||||
control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
|
||||
|
||||
if ((status & 0x80) || (control & 0x80)) {
|
||||
/* RTC not running */
|
||||
u8 buf[16];
|
||||
struct i2c_msg msg[1];
|
||||
|
||||
dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
|
||||
|
||||
/* Initialize all, including STATUS and CONTROL to zero */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
msg[0].addr = client->addr;
|
||||
msg[0].flags = 0;
|
||||
msg[0].len = sizeof(buf);
|
||||
msg[0].buf = &buf[0];
|
||||
|
||||
i2c_transfer(client->adapter, msg, 1);
|
||||
} else {
|
||||
/* Running: ensure that device is set in 24-hour mode */
|
||||
s32 val;
|
||||
|
||||
val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
|
||||
if ((val >= 0) && (val & (1 << 6)))
|
||||
i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
|
||||
val & 0x3f);
|
||||
}
|
||||
}
|
||||
|
||||
static int ds1337_detach_client(struct i2c_client *client)
|
||||
|
|
|
@ -232,10 +232,10 @@ static int ds1374_detach(struct i2c_client *client)
|
|||
}
|
||||
|
||||
static struct i2c_driver ds1374_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DS1374_DRV_NAME,
|
||||
.driver = {
|
||||
.name = DS1374_DRV_NAME,
|
||||
},
|
||||
.id = I2C_DRIVERID_DS1374,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = ds1374_attach,
|
||||
.detach_client = ds1374_detach,
|
||||
};
|
||||
|
|
|
@ -68,10 +68,10 @@ static int eeprom_detach_client(struct i2c_client *client);
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver eeprom_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "eeprom",
|
||||
.driver = {
|
||||
.name = "eeprom",
|
||||
},
|
||||
.id = I2C_DRIVERID_EEPROM,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = eeprom_attach_adapter,
|
||||
.detach_client = eeprom_detach_client,
|
||||
};
|
||||
|
|
|
@ -1632,11 +1632,11 @@ static int isp1301_scan_bus(struct i2c_adapter *bus)
|
|||
}
|
||||
|
||||
static struct i2c_driver isp1301_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "isp1301_omap",
|
||||
.driver = {
|
||||
.name = "isp1301_omap",
|
||||
},
|
||||
.id = 1301, /* FIXME "official", i2c-ids.h */
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = isp1301_scan_bus,
|
||||
.detach_client = isp1301_detach_client,
|
||||
};
|
||||
|
|
|
@ -211,10 +211,10 @@ m41t00_detach(struct i2c_client *client)
|
|||
}
|
||||
|
||||
static struct i2c_driver m41t00_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = M41T00_DRV_NAME,
|
||||
.driver = {
|
||||
.name = M41T00_DRV_NAME,
|
||||
},
|
||||
.id = I2C_DRIVERID_STM41T00,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = m41t00_attach,
|
||||
.detach_client = m41t00_detach,
|
||||
};
|
||||
|
|
|
@ -67,9 +67,9 @@ static int max6875_detach_client(struct i2c_client *client);
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver max6875_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "max6875",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "max6875",
|
||||
},
|
||||
.attach_adapter = max6875_attach_adapter,
|
||||
.detach_client = max6875_detach_client,
|
||||
};
|
||||
|
|
|
@ -38,9 +38,9 @@ static int pca9539_detach_client(struct i2c_client *client);
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver pca9539_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pca9539",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "pca9539",
|
||||
},
|
||||
.attach_adapter = pca9539_attach_adapter,
|
||||
.detach_client = pca9539_detach_client,
|
||||
};
|
||||
|
|
|
@ -65,10 +65,10 @@ static void pcf8574_init_client(struct i2c_client *client);
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver pcf8574_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pcf8574",
|
||||
.driver = {
|
||||
.name = "pcf8574",
|
||||
},
|
||||
.id = I2C_DRIVERID_PCF8574,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = pcf8574_attach_adapter,
|
||||
.detach_client = pcf8574_detach_client,
|
||||
};
|
||||
|
|
|
@ -88,10 +88,10 @@ static int pcf8591_read_channel(struct device *dev, int channel);
|
|||
|
||||
/* This is the driver that will be inserted */
|
||||
static struct i2c_driver pcf8591_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pcf8591",
|
||||
.driver = {
|
||||
.name = "pcf8591",
|
||||
},
|
||||
.id = I2C_DRIVERID_PCF8591,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = pcf8591_attach_adapter,
|
||||
.detach_client = pcf8591_detach_client,
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
|
@ -52,9 +53,6 @@ static inline u8 _rtc8564_ctrl2(struct i2c_client *client)
|
|||
#define CTRL1(c) _rtc8564_ctrl1(c)
|
||||
#define CTRL2(c) _rtc8564_ctrl2(c)
|
||||
|
||||
#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
|
||||
#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
|
||||
|
||||
static int debug;;
|
||||
module_param(debug, int, S_IRUGO | S_IWUSR);
|
||||
|
||||
|
@ -157,7 +155,6 @@ static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind)
|
|||
|
||||
strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
|
||||
i2c_set_clientdata(new_client, d);
|
||||
new_client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
new_client->addr = addr;
|
||||
new_client->adapter = adap;
|
||||
new_client->driver = &rtc8564_driver;
|
||||
|
@ -224,16 +221,16 @@ static int rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
|
|||
return ret;
|
||||
|
||||
/* century stored in minute alarm reg */
|
||||
dt->year = BCD_TO_BIN(buf[RTC8564_REG_YEAR]);
|
||||
dt->year += 100 * BCD_TO_BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
|
||||
dt->mday = BCD_TO_BIN(buf[RTC8564_REG_DAY] & 0x3f);
|
||||
dt->wday = BCD_TO_BIN(buf[RTC8564_REG_WDAY] & 7);
|
||||
dt->mon = BCD_TO_BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
|
||||
dt->year = BCD2BIN(buf[RTC8564_REG_YEAR]);
|
||||
dt->year += 100 * BCD2BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
|
||||
dt->mday = BCD2BIN(buf[RTC8564_REG_DAY] & 0x3f);
|
||||
dt->wday = BCD2BIN(buf[RTC8564_REG_WDAY] & 7);
|
||||
dt->mon = BCD2BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
|
||||
|
||||
dt->secs = BCD_TO_BIN(buf[RTC8564_REG_SEC] & 0x7f);
|
||||
dt->secs = BCD2BIN(buf[RTC8564_REG_SEC] & 0x7f);
|
||||
dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80;
|
||||
dt->mins = BCD_TO_BIN(buf[RTC8564_REG_MIN] & 0x7f);
|
||||
dt->hours = BCD_TO_BIN(buf[RTC8564_REG_HR] & 0x3f);
|
||||
dt->mins = BCD2BIN(buf[RTC8564_REG_MIN] & 0x7f);
|
||||
dt->hours = BCD2BIN(buf[RTC8564_REG_HR] & 0x3f);
|
||||
|
||||
_DBGRTCTM(2, *dt);
|
||||
|
||||
|
@ -255,18 +252,18 @@ rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
|
|||
|
||||
buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP;
|
||||
buf[RTC8564_REG_CTRL2] = CTRL2(client);
|
||||
buf[RTC8564_REG_SEC] = BIN_TO_BCD(dt->secs);
|
||||
buf[RTC8564_REG_MIN] = BIN_TO_BCD(dt->mins);
|
||||
buf[RTC8564_REG_HR] = BIN_TO_BCD(dt->hours);
|
||||
buf[RTC8564_REG_SEC] = BIN2BCD(dt->secs);
|
||||
buf[RTC8564_REG_MIN] = BIN2BCD(dt->mins);
|
||||
buf[RTC8564_REG_HR] = BIN2BCD(dt->hours);
|
||||
|
||||
if (datetoo) {
|
||||
len += 5;
|
||||
buf[RTC8564_REG_DAY] = BIN_TO_BCD(dt->mday);
|
||||
buf[RTC8564_REG_WDAY] = BIN_TO_BCD(dt->wday);
|
||||
buf[RTC8564_REG_MON_CENT] = BIN_TO_BCD(dt->mon) & 0x1f;
|
||||
buf[RTC8564_REG_DAY] = BIN2BCD(dt->mday);
|
||||
buf[RTC8564_REG_WDAY] = BIN2BCD(dt->wday);
|
||||
buf[RTC8564_REG_MON_CENT] = BIN2BCD(dt->mon) & 0x1f;
|
||||
/* century stored in minute alarm reg */
|
||||
buf[RTC8564_REG_YEAR] = BIN_TO_BCD(dt->year % 100);
|
||||
buf[RTC8564_REG_AL_MIN] = BIN_TO_BCD(dt->year / 100);
|
||||
buf[RTC8564_REG_YEAR] = BIN2BCD(dt->year % 100);
|
||||
buf[RTC8564_REG_AL_MIN] = BIN2BCD(dt->year / 100);
|
||||
}
|
||||
|
||||
ret = rtc8564_write(client, 0, buf, len);
|
||||
|
@ -361,10 +358,10 @@ rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||
}
|
||||
|
||||
static struct i2c_driver rtc8564_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "RTC8564",
|
||||
.driver = {
|
||||
.name = "RTC8564",
|
||||
},
|
||||
.id = I2C_DRIVERID_RTC8564,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = rtc8564_probe,
|
||||
.detach_client = rtc8564_detach,
|
||||
.command = rtc8564_command
|
||||
|
|
|
@ -637,9 +637,9 @@ static int __init tps65010_scan_bus(struct i2c_adapter *bus)
|
|||
}
|
||||
|
||||
static struct i2c_driver tps65010_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "tps65010",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "tps65010",
|
||||
},
|
||||
.attach_adapter = tps65010_scan_bus,
|
||||
.detach_client = __exit_p(tps65010_detach_client),
|
||||
};
|
||||
|
|
|
@ -105,9 +105,9 @@ static int x1205_command(struct i2c_client *client, unsigned int cmd,
|
|||
void *arg);
|
||||
|
||||
static struct i2c_driver x1205_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "x1205",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "x1205",
|
||||
},
|
||||
.attach_adapter = &x1205_attach,
|
||||
.detach_client = &x1205_detach,
|
||||
};
|
||||
|
|
|
@ -197,7 +197,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
|
|||
/* inform drivers of new adapters */
|
||||
list_for_each(item,&drivers) {
|
||||
driver = list_entry(item, struct i2c_driver, list);
|
||||
if (driver->flags & I2C_DF_NOTIFY)
|
||||
if (driver->attach_adapter)
|
||||
/* We ignore the return code; if it fails, too bad */
|
||||
driver->attach_adapter(adap);
|
||||
}
|
||||
|
@ -235,7 +235,8 @@ int i2c_del_adapter(struct i2c_adapter *adap)
|
|||
if (driver->detach_adapter)
|
||||
if ((res = driver->detach_adapter(adap))) {
|
||||
dev_err(&adap->dev, "detach_adapter failed "
|
||||
"for driver [%s]\n", driver->name);
|
||||
"for driver [%s]\n",
|
||||
driver->driver.name);
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
|
@ -245,10 +246,6 @@ int i2c_del_adapter(struct i2c_adapter *adap)
|
|||
list_for_each_safe(item, _n, &adap->clients) {
|
||||
client = list_entry(item, struct i2c_client, list);
|
||||
|
||||
/* detaching devices is unconditional of the set notify
|
||||
* flag, as _all_ clients that reside on the adapter
|
||||
* must be deleted, as this would cause invalid states.
|
||||
*/
|
||||
if ((res=client->driver->detach_client(client))) {
|
||||
dev_err(&adap->dev, "detach_client failed for client "
|
||||
"[%s] at address 0x%02x\n", client->name,
|
||||
|
@ -286,7 +283,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
|
|||
* chips.
|
||||
*/
|
||||
|
||||
int i2c_add_driver(struct i2c_driver *driver)
|
||||
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
|
||||
{
|
||||
struct list_head *item;
|
||||
struct i2c_adapter *adapter;
|
||||
|
@ -295,8 +292,7 @@ int i2c_add_driver(struct i2c_driver *driver)
|
|||
down(&core_lists);
|
||||
|
||||
/* add the driver to the list of i2c drivers in the driver core */
|
||||
driver->driver.owner = driver->owner;
|
||||
driver->driver.name = driver->name;
|
||||
driver->driver.owner = owner;
|
||||
driver->driver.bus = &i2c_bus_type;
|
||||
driver->driver.probe = i2c_device_probe;
|
||||
driver->driver.remove = i2c_device_remove;
|
||||
|
@ -306,10 +302,10 @@ int i2c_add_driver(struct i2c_driver *driver)
|
|||
goto out_unlock;
|
||||
|
||||
list_add_tail(&driver->list,&drivers);
|
||||
pr_debug("i2c-core: driver [%s] registered\n", driver->name);
|
||||
pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
|
||||
|
||||
/* now look for instances of driver on our adapters */
|
||||
if (driver->flags & I2C_DF_NOTIFY) {
|
||||
if (driver->attach_adapter) {
|
||||
list_for_each(item,&adapters) {
|
||||
adapter = list_entry(item, struct i2c_adapter, list);
|
||||
driver->attach_adapter(adapter);
|
||||
|
@ -320,6 +316,7 @@ int i2c_add_driver(struct i2c_driver *driver)
|
|||
up(&core_lists);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(i2c_register_driver);
|
||||
|
||||
int i2c_del_driver(struct i2c_driver *driver)
|
||||
{
|
||||
|
@ -334,17 +331,14 @@ int i2c_del_driver(struct i2c_driver *driver)
|
|||
/* Have a look at each adapter, if clients of this driver are still
|
||||
* attached. If so, detach them to be able to kill the driver
|
||||
* afterwards.
|
||||
*
|
||||
* Removing clients does not depend on the notify flag, else
|
||||
* invalid operation might (will!) result, when using stale client
|
||||
* pointers.
|
||||
*/
|
||||
list_for_each(item1,&adapters) {
|
||||
adap = list_entry(item1, struct i2c_adapter, list);
|
||||
if (driver->detach_adapter) {
|
||||
if ((res = driver->detach_adapter(adap))) {
|
||||
dev_err(&adap->dev, "detach_adapter failed "
|
||||
"for driver [%s]\n", driver->name);
|
||||
"for driver [%s]\n",
|
||||
driver->driver.name);
|
||||
goto out_unlock;
|
||||
}
|
||||
} else {
|
||||
|
@ -368,7 +362,7 @@ int i2c_del_driver(struct i2c_driver *driver)
|
|||
|
||||
driver_unregister(&driver->driver);
|
||||
list_del(&driver->list);
|
||||
pr_debug("i2c-core: driver [%s] unregistered\n", driver->name);
|
||||
pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
|
||||
|
||||
out_unlock:
|
||||
up(&core_lists);
|
||||
|
@ -419,8 +413,7 @@ int i2c_attach_client(struct i2c_client *client)
|
|||
}
|
||||
}
|
||||
|
||||
if (client->flags & I2C_CLIENT_ALLOW_USE)
|
||||
client->usage_count = 0;
|
||||
client->usage_count = 0;
|
||||
|
||||
client->dev.parent = &client->adapter->dev;
|
||||
client->dev.driver = &client->driver->driver;
|
||||
|
@ -443,8 +436,7 @@ int i2c_detach_client(struct i2c_client *client)
|
|||
struct i2c_adapter *adapter = client->adapter;
|
||||
int res = 0;
|
||||
|
||||
if ((client->flags & I2C_CLIENT_ALLOW_USE)
|
||||
&& (client->usage_count > 0)) {
|
||||
if (client->usage_count > 0) {
|
||||
dev_warn(&client->dev, "Client [%s] still busy, "
|
||||
"can't detach\n", client->name);
|
||||
return -EBUSY;
|
||||
|
@ -475,10 +467,10 @@ int i2c_detach_client(struct i2c_client *client)
|
|||
static int i2c_inc_use_client(struct i2c_client *client)
|
||||
{
|
||||
|
||||
if (!try_module_get(client->driver->owner))
|
||||
if (!try_module_get(client->driver->driver.owner))
|
||||
return -ENODEV;
|
||||
if (!try_module_get(client->adapter->owner)) {
|
||||
module_put(client->driver->owner);
|
||||
module_put(client->driver->driver.owner);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -487,7 +479,7 @@ static int i2c_inc_use_client(struct i2c_client *client)
|
|||
|
||||
static void i2c_dec_use_client(struct i2c_client *client)
|
||||
{
|
||||
module_put(client->driver->owner);
|
||||
module_put(client->driver->driver.owner);
|
||||
module_put(client->adapter->owner);
|
||||
}
|
||||
|
||||
|
@ -499,33 +491,20 @@ int i2c_use_client(struct i2c_client *client)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (client->flags & I2C_CLIENT_ALLOW_USE) {
|
||||
if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE)
|
||||
client->usage_count++;
|
||||
else if (client->usage_count > 0)
|
||||
goto busy;
|
||||
else
|
||||
client->usage_count++;
|
||||
}
|
||||
client->usage_count++;
|
||||
|
||||
return 0;
|
||||
busy:
|
||||
i2c_dec_use_client(client);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
int i2c_release_client(struct i2c_client *client)
|
||||
{
|
||||
if(client->flags & I2C_CLIENT_ALLOW_USE) {
|
||||
if(client->usage_count>0)
|
||||
client->usage_count--;
|
||||
else {
|
||||
pr_debug("i2c-core: %s used one too many times\n",
|
||||
__FUNCTION__);
|
||||
return -EPERM;
|
||||
}
|
||||
if (!client->usage_count) {
|
||||
pr_debug("i2c-core: %s used one too many times\n",
|
||||
__FUNCTION__);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
client->usage_count--;
|
||||
i2c_dec_use_client(client);
|
||||
|
||||
return 0;
|
||||
|
@ -539,14 +518,14 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
|
|||
down(&adap->clist_lock);
|
||||
list_for_each(item,&adap->clients) {
|
||||
client = list_entry(item, struct i2c_client, list);
|
||||
if (!try_module_get(client->driver->owner))
|
||||
if (!try_module_get(client->driver->driver.owner))
|
||||
continue;
|
||||
if (NULL != client->driver->command) {
|
||||
up(&adap->clist_lock);
|
||||
client->driver->command(client,cmd,arg);
|
||||
down(&adap->clist_lock);
|
||||
}
|
||||
module_put(client->driver->owner);
|
||||
module_put(client->driver->driver.owner);
|
||||
}
|
||||
up(&adap->clist_lock);
|
||||
}
|
||||
|
@ -1147,7 +1126,6 @@ EXPORT_SYMBOL_GPL(i2c_bus_type);
|
|||
|
||||
EXPORT_SYMBOL(i2c_add_adapter);
|
||||
EXPORT_SYMBOL(i2c_del_adapter);
|
||||
EXPORT_SYMBOL(i2c_add_driver);
|
||||
EXPORT_SYMBOL(i2c_del_driver);
|
||||
EXPORT_SYMBOL(i2c_attach_client);
|
||||
EXPORT_SYMBOL(i2c_detach_client);
|
||||
|
|
|
@ -42,8 +42,7 @@ static struct i2c_client i2cdev_client_template;
|
|||
struct i2c_dev {
|
||||
int minor;
|
||||
struct i2c_adapter *adap;
|
||||
struct class_device class_dev;
|
||||
struct completion released; /* FIXME, we need a class_device_unregister() */
|
||||
struct class_device *class_dev;
|
||||
};
|
||||
#define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev)
|
||||
|
||||
|
@ -105,7 +104,10 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev)
|
|||
|
||||
static ssize_t show_adapter_name(struct class_device *class_dev, char *buf)
|
||||
{
|
||||
struct i2c_dev *i2c_dev = to_i2c_dev(class_dev);
|
||||
struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(class_dev->devt));
|
||||
|
||||
if (!i2c_dev)
|
||||
return -ENODEV;
|
||||
return sprintf(buf, "%s\n", i2c_dev->adap->name);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
|
||||
|
@ -408,21 +410,12 @@ static struct file_operations i2cdev_fops = {
|
|||
.release = i2cdev_release,
|
||||
};
|
||||
|
||||
static void release_i2c_dev(struct class_device *dev)
|
||||
{
|
||||
struct i2c_dev *i2c_dev = to_i2c_dev(dev);
|
||||
complete(&i2c_dev->released);
|
||||
}
|
||||
|
||||
static struct class i2c_dev_class = {
|
||||
.name = "i2c-dev",
|
||||
.release = &release_i2c_dev,
|
||||
};
|
||||
static struct class *i2c_dev_class;
|
||||
|
||||
static int i2cdev_attach_adapter(struct i2c_adapter *adap)
|
||||
{
|
||||
struct i2c_dev *i2c_dev;
|
||||
int retval;
|
||||
struct device *dev;
|
||||
|
||||
i2c_dev = get_free_i2c_dev(adap);
|
||||
if (IS_ERR(i2c_dev))
|
||||
|
@ -434,21 +427,20 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
|
|||
/* register this i2c device with the driver core */
|
||||
i2c_dev->adap = adap;
|
||||
if (adap->dev.parent == &platform_bus)
|
||||
i2c_dev->class_dev.dev = &adap->dev;
|
||||
dev = &adap->dev;
|
||||
else
|
||||
i2c_dev->class_dev.dev = adap->dev.parent;
|
||||
i2c_dev->class_dev.class = &i2c_dev_class;
|
||||
i2c_dev->class_dev.devt = MKDEV(I2C_MAJOR, i2c_dev->minor);
|
||||
snprintf(i2c_dev->class_dev.class_id, BUS_ID_SIZE, "i2c-%d", i2c_dev->minor);
|
||||
retval = class_device_register(&i2c_dev->class_dev);
|
||||
if (retval)
|
||||
dev = adap->dev.parent;
|
||||
i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL,
|
||||
MKDEV(I2C_MAJOR, i2c_dev->minor),
|
||||
dev, "i2c-%d", i2c_dev->minor);
|
||||
if (!i2c_dev->class_dev)
|
||||
goto error;
|
||||
class_device_create_file(&i2c_dev->class_dev, &class_device_attr_name);
|
||||
class_device_create_file(i2c_dev->class_dev, &class_device_attr_name);
|
||||
return 0;
|
||||
error:
|
||||
return_i2c_dev(i2c_dev);
|
||||
kfree(i2c_dev);
|
||||
return retval;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int i2cdev_detach_adapter(struct i2c_adapter *adap)
|
||||
|
@ -459,10 +451,8 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap)
|
|||
if (!i2c_dev)
|
||||
return -ENODEV;
|
||||
|
||||
init_completion(&i2c_dev->released);
|
||||
return_i2c_dev(i2c_dev);
|
||||
class_device_unregister(&i2c_dev->class_dev);
|
||||
wait_for_completion(&i2c_dev->released);
|
||||
class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, i2c_dev->minor));
|
||||
kfree(i2c_dev);
|
||||
|
||||
pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name);
|
||||
|
@ -474,21 +464,14 @@ static int i2cdev_detach_client(struct i2c_client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
|
||||
void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct i2c_driver i2cdev_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "dev_driver",
|
||||
.driver = {
|
||||
.name = "dev_driver",
|
||||
},
|
||||
.id = I2C_DRIVERID_I2CDEV,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = i2cdev_attach_adapter,
|
||||
.detach_adapter = i2cdev_detach_adapter,
|
||||
.detach_client = i2cdev_detach_client,
|
||||
.command = i2cdev_command,
|
||||
};
|
||||
|
||||
static struct i2c_client i2cdev_client_template = {
|
||||
|
@ -507,8 +490,8 @@ static int __init i2c_dev_init(void)
|
|||
if (res)
|
||||
goto out;
|
||||
|
||||
res = class_register(&i2c_dev_class);
|
||||
if (res)
|
||||
i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
|
||||
if (IS_ERR(i2c_dev_class))
|
||||
goto out_unreg_chrdev;
|
||||
|
||||
res = i2c_add_driver(&i2cdev_driver);
|
||||
|
@ -518,7 +501,7 @@ static int __init i2c_dev_init(void)
|
|||
return 0;
|
||||
|
||||
out_unreg_class:
|
||||
class_unregister(&i2c_dev_class);
|
||||
class_destroy(i2c_dev_class);
|
||||
out_unreg_chrdev:
|
||||
unregister_chrdev(I2C_MAJOR, "i2c");
|
||||
out:
|
||||
|
@ -529,7 +512,7 @@ out:
|
|||
static void __exit i2c_dev_exit(void)
|
||||
{
|
||||
i2c_del_driver(&i2cdev_driver);
|
||||
class_unregister(&i2c_dev_class);
|
||||
class_destroy(i2c_dev_class);
|
||||
unregister_chrdev(I2C_MAJOR,"i2c");
|
||||
}
|
||||
|
||||
|
|
|
@ -176,9 +176,9 @@ detach_thermostat(struct i2c_adapter *adapter)
|
|||
}
|
||||
|
||||
static struct i2c_driver thermostat_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "therm_adt746x",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "therm_adt746x",
|
||||
},
|
||||
.attach_adapter = attach_thermostat,
|
||||
.detach_adapter = detach_thermostat,
|
||||
};
|
||||
|
|
|
@ -283,9 +283,9 @@ static int therm_pm72_detach(struct i2c_adapter *adapter);
|
|||
|
||||
static struct i2c_driver therm_pm72_driver =
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
.name = "therm_pm72",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "therm_pm72",
|
||||
},
|
||||
.attach_adapter = therm_pm72_attach,
|
||||
.detach_adapter = therm_pm72_detach,
|
||||
};
|
||||
|
|
|
@ -354,10 +354,10 @@ do_detach( struct i2c_client *client )
|
|||
}
|
||||
|
||||
static struct i2c_driver g4fan_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "therm_windtunnel",
|
||||
.driver = {
|
||||
.name = "therm_windtunnel",
|
||||
},
|
||||
.id = I2C_DRIVERID_G4FAN,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = do_attach,
|
||||
.detach_client = do_detach,
|
||||
};
|
||||
|
|
|
@ -47,9 +47,9 @@ static int wf_lm75_attach(struct i2c_adapter *adapter);
|
|||
static int wf_lm75_detach(struct i2c_client *client);
|
||||
|
||||
static struct i2c_driver wf_lm75_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "wf_lm75",
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.driver = {
|
||||
.name = "wf_lm75",
|
||||
},
|
||||
.attach_adapter = wf_lm75_attach,
|
||||
.detach_client = wf_lm75_detach,
|
||||
};
|
||||
|
|
|
@ -60,7 +60,7 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
|
|||
#define dprintk(level, args...) \
|
||||
do { \
|
||||
if ((debug & level)) { \
|
||||
printk("%s: %s(): ", __stringify(KBUILD_MODNAME), \
|
||||
printk("%s: %s(): ", KBUILD_MODNAME, \
|
||||
__FUNCTION__); \
|
||||
printk(args); } \
|
||||
} while (0)
|
||||
|
|
|
@ -19,7 +19,7 @@ extern int budget_debug;
|
|||
#endif
|
||||
|
||||
#define dprintk(level,args...) \
|
||||
do { if ((budget_debug & level)) { printk("%s: %s(): ",__stringify(KBUILD_MODNAME), __FUNCTION__); printk(args); } } while (0)
|
||||
do { if ((budget_debug & level)) { printk("%s: %s(): ", KBUILD_MODNAME, __FUNCTION__); printk(args); } } while (0)
|
||||
|
||||
struct budget_info {
|
||||
char *name;
|
||||
|
|
|
@ -420,7 +420,6 @@ adv7170_detect_client (struct i2c_adapter *adapter,
|
|||
client->addr = address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &i2c_driver_adv7170;
|
||||
client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
if ((client->addr == I2C_ADV7170 >> 1) ||
|
||||
(client->addr == (I2C_ADV7170 >> 1) + 1)) {
|
||||
dname = adv7170_name;
|
||||
|
@ -498,11 +497,11 @@ adv7170_detach_client (struct i2c_client *client)
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver i2c_driver_adv7170 = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "adv7170", /* name */
|
||||
.driver = {
|
||||
.name = "adv7170", /* name */
|
||||
},
|
||||
|
||||
.id = I2C_DRIVERID_ADV7170,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
|
||||
.attach_adapter = adv7170_attach_adapter,
|
||||
.detach_client = adv7170_detach_client,
|
||||
|
|
|
@ -470,7 +470,6 @@ adv7175_detect_client (struct i2c_adapter *adapter,
|
|||
client->addr = address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &i2c_driver_adv7175;
|
||||
client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
if ((client->addr == I2C_ADV7175 >> 1) ||
|
||||
(client->addr == (I2C_ADV7175 >> 1) + 1)) {
|
||||
dname = adv7175_name;
|
||||
|
@ -548,11 +547,11 @@ adv7175_detach_client (struct i2c_client *client)
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver i2c_driver_adv7175 = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "adv7175", /* name */
|
||||
.driver = {
|
||||
.name = "adv7175", /* name */
|
||||
},
|
||||
|
||||
.id = I2C_DRIVERID_ADV7175,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
|
||||
.attach_adapter = adv7175_attach_adapter,
|
||||
.detach_client = adv7175_detach_client,
|
||||
|
|
|
@ -535,7 +535,6 @@ bt819_detect_client (struct i2c_adapter *adapter,
|
|||
client->addr = address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &i2c_driver_bt819;
|
||||
client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
|
||||
decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL);
|
||||
if (decoder == NULL) {
|
||||
|
@ -623,11 +622,11 @@ bt819_detach_client (struct i2c_client *client)
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver i2c_driver_bt819 = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "bt819",
|
||||
.driver = {
|
||||
.name = "bt819",
|
||||
},
|
||||
|
||||
.id = I2C_DRIVERID_BT819,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
|
||||
.attach_adapter = bt819_attach_adapter,
|
||||
.detach_client = bt819_detach_client,
|
||||
|
|
|
@ -230,10 +230,10 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "i2c bt832 driver",
|
||||
.driver = {
|
||||
.name = "i2c bt832 driver",
|
||||
},
|
||||
.id = -1, /* FIXME */
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = bt832_probe,
|
||||
.detach_client = bt832_detach,
|
||||
.command = bt832_command,
|
||||
|
@ -241,7 +241,6 @@ static struct i2c_driver driver = {
|
|||
static struct i2c_client client_template =
|
||||
{
|
||||
.name = "bt832",
|
||||
.flags = I2C_CLIENT_ALLOW_USE,
|
||||
.driver = &driver,
|
||||
};
|
||||
|
||||
|
|
|
@ -323,7 +323,6 @@ bt856_detect_client (struct i2c_adapter *adapter,
|
|||
client->addr = address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &i2c_driver_bt856;
|
||||
client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client)));
|
||||
|
||||
encoder = kmalloc(sizeof(struct bt856), GFP_KERNEL);
|
||||
|
@ -405,11 +404,11 @@ bt856_detach_client (struct i2c_client *client)
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver i2c_driver_bt856 = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "bt856",
|
||||
.driver = {
|
||||
.name = "bt856",
|
||||
},
|
||||
|
||||
.id = I2C_DRIVERID_BT856,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
|
||||
.attach_adapter = bt856_attach_adapter,
|
||||
.detach_client = bt856_detach_client,
|
||||
|
|
|
@ -300,7 +300,7 @@ static int attach_inform(struct i2c_client *client)
|
|||
|
||||
if (bttv_debug)
|
||||
printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
|
||||
btv->c.nr,client->driver->name,client->addr,
|
||||
btv->c.nr, client->driver->driver.name, client->addr,
|
||||
client->name);
|
||||
if (!client->driver->command)
|
||||
return 0;
|
||||
|
|
|
@ -42,15 +42,16 @@ MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On");
|
|||
#define cs53l32a_dbg(fmt, arg...) \
|
||||
do { \
|
||||
if (debug) \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, \
|
||||
client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); \
|
||||
} while (0)
|
||||
|
||||
#define cs53l32a_err(fmt, arg...) do { \
|
||||
printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
|
||||
#define cs53l32a_info(fmt, arg...) do { \
|
||||
printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
|
||||
|
||||
static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
|
||||
|
@ -154,7 +155,6 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind)
|
|||
client->addr = address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &i2c_driver;
|
||||
client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
snprintf(client->name, sizeof(client->name) - 1, "cs53l32a");
|
||||
|
||||
cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
|
||||
|
@ -216,13 +216,13 @@ static int cs53l32a_detach(struct i2c_client *client)
|
|||
|
||||
/* i2c implementation */
|
||||
static struct i2c_driver i2c_driver = {
|
||||
.name = "cs53l32a",
|
||||
.driver = {
|
||||
.name = "cs53l32a",
|
||||
},
|
||||
.id = I2C_DRIVERID_CS53L32A,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = cs53l32a_probe,
|
||||
.detach_client = cs53l32a_detach,
|
||||
.command = cs53l32a_command,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -773,7 +773,6 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
|
|||
client->addr = address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &i2c_driver_cx25840;
|
||||
client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
snprintf(client->name, sizeof(client->name) - 1, "cx25840");
|
||||
|
||||
cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1);
|
||||
|
@ -844,15 +843,15 @@ static int cx25840_detach_client(struct i2c_client *client)
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver i2c_driver_cx25840 = {
|
||||
.name = "cx25840",
|
||||
.driver = {
|
||||
.name = "cx25840",
|
||||
},
|
||||
|
||||
.id = I2C_DRIVERID_CX25840,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
|
||||
.attach_adapter = cx25840_attach_adapter,
|
||||
.detach_client = cx25840_detach_client,
|
||||
.command = cx25840_command,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,15 +27,16 @@
|
|||
extern int cx25840_debug;
|
||||
|
||||
#define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, \
|
||||
client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
|
||||
|
||||
#define cx25840_err(fmt, arg...) do { \
|
||||
printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
|
||||
|
||||
#define cx25840_info(fmt, arg...) do { \
|
||||
printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
|
||||
|
||||
#define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0)
|
||||
|
|
|
@ -94,7 +94,7 @@ static int attach_inform(struct i2c_client *client)
|
|||
struct cx88_core *core = i2c_get_adapdata(client->adapter);
|
||||
|
||||
dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
|
||||
client->driver->name, client->addr, client->name);
|
||||
client->driver->driver.name, client->addr, client->name);
|
||||
if (!client->driver->command)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -497,7 +497,6 @@ static struct i2c_adapter em28xx_adap_template = {
|
|||
|
||||
static struct i2c_client em28xx_client_template = {
|
||||
.name = "em28xx internal",
|
||||
.flags = I2C_CLIENT_ALLOW_USE,
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
|
|
|
@ -451,10 +451,10 @@ static int indycam_command(struct i2c_client *client, unsigned int cmd,
|
|||
}
|
||||
|
||||
static struct i2c_driver i2c_driver_indycam = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "indycam",
|
||||
.driver = {
|
||||
.name = "indycam",
|
||||
},
|
||||
.id = I2C_DRIVERID_INDYCAM,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = indycam_probe,
|
||||
.detach_client = indycam_detach,
|
||||
.command = indycam_command,
|
||||
|
|
|
@ -278,9 +278,10 @@ static int ir_detach(struct i2c_client *client);
|
|||
static int ir_probe(struct i2c_adapter *adap);
|
||||
|
||||
static struct i2c_driver driver = {
|
||||
.name = "ir remote kbd driver",
|
||||
.driver = {
|
||||
.name = "ir remote kbd driver",
|
||||
},
|
||||
.id = I2C_DRIVERID_INFRARED,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = ir_probe,
|
||||
.detach_client = ir_detach,
|
||||
};
|
||||
|
|
|
@ -59,7 +59,8 @@
|
|||
#define msp3400_dbg(fmt, arg...) \
|
||||
do { \
|
||||
if (debug) \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, \
|
||||
client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); \
|
||||
} while (0)
|
||||
|
||||
|
@ -67,7 +68,8 @@
|
|||
#define msp3400_dbg_mediumvol(fmt, arg...) \
|
||||
do { \
|
||||
if (debug >= 2) \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, \
|
||||
client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); \
|
||||
} while (0)
|
||||
|
||||
|
@ -75,18 +77,19 @@
|
|||
#define msp3400_dbg_highvol(fmt, arg...) \
|
||||
do { \
|
||||
if (debug >= 16) \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, \
|
||||
client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); \
|
||||
} while (0)
|
||||
|
||||
#define msp3400_err(fmt, arg...) do { \
|
||||
printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
|
||||
#define msp3400_warn(fmt, arg...) do { \
|
||||
printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
|
||||
#define msp3400_info(fmt, arg...) do { \
|
||||
printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
|
||||
|
||||
#define OPMODE_AUTO -1
|
||||
|
@ -1561,14 +1564,12 @@ static int msp_resume(struct device * dev);
|
|||
static void msp_wake_thread(struct i2c_client *client);
|
||||
|
||||
static struct i2c_driver driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "msp3400",
|
||||
.id = I2C_DRIVERID_MSP3400,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = msp_probe,
|
||||
.detach_client = msp_detach,
|
||||
.command = msp_command,
|
||||
.driver = {
|
||||
.name = "i2c msp3400 driver",
|
||||
.suspend = msp_suspend,
|
||||
.resume = msp_resume,
|
||||
},
|
||||
|
@ -1577,7 +1578,6 @@ static struct i2c_driver driver = {
|
|||
static struct i2c_client client_template =
|
||||
{
|
||||
.name = "(unset)",
|
||||
.flags = I2C_CLIENT_ALLOW_USE,
|
||||
.driver = &driver,
|
||||
};
|
||||
|
||||
|
|
|
@ -410,11 +410,11 @@ static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg)
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ovcamchip",
|
||||
.driver = {
|
||||
.name = "ovcamchip",
|
||||
},
|
||||
.id = I2C_DRIVERID_OVCAMCHIP,
|
||||
.class = I2C_CLASS_CAM_DIGITAL,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = ovcamchip_attach,
|
||||
.detach_client = ovcamchip_detach,
|
||||
.command = ovcamchip_command,
|
||||
|
|
|
@ -151,25 +151,18 @@ static int saa5246a_detach(struct i2c_client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int saa5246a_command(struct i2c_client *device, unsigned int cmd,
|
||||
void *arg)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* I2C interfaces
|
||||
*/
|
||||
|
||||
static struct i2c_driver i2c_driver_videotext =
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
.name = IF_NAME, /* name */
|
||||
.driver = {
|
||||
.name = IF_NAME, /* name */
|
||||
},
|
||||
.id = I2C_DRIVERID_SAA5249, /* in i2c.h */
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = saa5246a_probe,
|
||||
.detach_client = saa5246a_detach,
|
||||
.command = saa5246a_command
|
||||
};
|
||||
|
||||
static struct i2c_client client_template = {
|
||||
|
|
|
@ -226,23 +226,16 @@ static int saa5249_detach(struct i2c_client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int saa5249_command(struct i2c_client *device,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* new I2C driver support */
|
||||
|
||||
static struct i2c_driver i2c_driver_videotext =
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
.name = IF_NAME, /* name */
|
||||
.driver = {
|
||||
.name = IF_NAME, /* name */
|
||||
},
|
||||
.id = I2C_DRIVERID_SAA5249, /* in i2c.h */
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = saa5249_probe,
|
||||
.detach_client = saa5249_detach,
|
||||
.command = saa5249_command
|
||||
};
|
||||
|
||||
static struct i2c_client client_template = {
|
||||
|
|
|
@ -495,10 +495,10 @@ static int saa6588_command(struct i2c_client *client, unsigned int cmd,
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "i2c saa6588 driver",
|
||||
.driver = {
|
||||
.name = "i2c saa6588 driver",
|
||||
},
|
||||
.id = -1, /* FIXME */
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = saa6588_probe,
|
||||
.detach_client = saa6588_detach,
|
||||
.command = saa6588_command,
|
||||
|
@ -506,7 +506,6 @@ static struct i2c_driver driver = {
|
|||
|
||||
static struct i2c_client client_template = {
|
||||
.name = "saa6588",
|
||||
.flags = I2C_CLIENT_ALLOW_USE,
|
||||
.driver = &driver,
|
||||
};
|
||||
|
||||
|
|
|
@ -501,7 +501,6 @@ saa7110_detect_client (struct i2c_adapter *adapter,
|
|||
client->addr = address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &i2c_driver_saa7110;
|
||||
client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client)));
|
||||
|
||||
decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL);
|
||||
|
@ -587,11 +586,11 @@ saa7110_detach_client (struct i2c_client *client)
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver i2c_driver_saa7110 = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "saa7110",
|
||||
.driver = {
|
||||
.name = "saa7110",
|
||||
},
|
||||
|
||||
.id = I2C_DRIVERID_SAA7110,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
|
||||
.attach_adapter = saa7110_attach_adapter,
|
||||
.detach_client = saa7110_detach_client,
|
||||
|
|
|
@ -518,7 +518,6 @@ saa7111_detect_client (struct i2c_adapter *adapter,
|
|||
client->addr = address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &i2c_driver_saa7111;
|
||||
client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client)));
|
||||
|
||||
decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL);
|
||||
|
@ -590,11 +589,11 @@ saa7111_detach_client (struct i2c_client *client)
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver i2c_driver_saa7111 = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "saa7111",
|
||||
.driver = {
|
||||
.name = "saa7111",
|
||||
},
|
||||
|
||||
.id = I2C_DRIVERID_SAA7111A,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
|
||||
.attach_adapter = saa7111_attach_adapter,
|
||||
.detach_client = saa7111_detach_client,
|
||||
|
|
|
@ -859,7 +859,6 @@ saa7114_detect_client (struct i2c_adapter *adapter,
|
|||
client->addr = address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &i2c_driver_saa7114;
|
||||
client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
|
||||
|
||||
decoder = kmalloc(sizeof(struct saa7114), GFP_KERNEL);
|
||||
|
@ -1204,11 +1203,11 @@ saa7114_detach_client (struct i2c_client *client)
|
|||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static struct i2c_driver i2c_driver_saa7114 = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "saa7114",
|
||||
.driver = {
|
||||
.name = "saa7114",
|
||||
},
|
||||
|
||||
.id = I2C_DRIVERID_SAA7114,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
|
||||
.attach_adapter = saa7114_attach_adapter,
|
||||
.detach_client = saa7114_detach_client,
|
||||
|
|
|
@ -52,15 +52,16 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
|
|||
#define saa7115_dbg(fmt,arg...) \
|
||||
do { \
|
||||
if (debug) \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_INFO "%s debug %d-%04x: " fmt, \
|
||||
client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); \
|
||||
} while (0)
|
||||
|
||||
#define saa7115_err(fmt, arg...) do { \
|
||||
printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
|
||||
#define saa7115_info(fmt, arg...) do { \
|
||||
printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
|
||||
printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
|
||||
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
|
||||
|
||||
static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
|
||||
|
@ -1270,7 +1271,6 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
|
|||
client->addr = address;
|
||||
client->adapter = adapter;
|
||||
client->driver = &i2c_driver_saa7115;
|
||||
client->flags = I2C_CLIENT_ALLOW_USE;
|
||||
snprintf(client->name, sizeof(client->name) - 1, "saa7115");
|
||||
|
||||
saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1);
|
||||
|
@ -1354,13 +1354,13 @@ static int saa7115_detach(struct i2c_client *client)
|
|||
|
||||
/* i2c implementation */
|
||||
static struct i2c_driver i2c_driver_saa7115 = {
|
||||
.name = "saa7115",
|
||||
.driver = {
|
||||
.name = "saa7115",
|
||||
},
|
||||
.id = I2C_DRIVERID_SAA711X,
|
||||
.flags = I2C_DF_NOTIFY,
|
||||
.attach_adapter = saa7115_probe,
|
||||
.detach_client = saa7115_detach,
|
||||
.command = saa7115_command,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue