Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
6fd6bef3
Commit
6fd6bef3
authored
Aug 01, 2003
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Plain Diff
Merge kroah.com:/home/greg/linux/BK/bleed-2.5
into kroah.com:/home/greg/linux/BK/i2c-2.5
parents
bd711a45
ae16b852
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
488 additions
and
149 deletions
+488
-149
drivers/i2c/Kconfig
drivers/i2c/Kconfig
+1
-3
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Kconfig
+17
-0
drivers/i2c/busses/Makefile
drivers/i2c/busses/Makefile
+1
-0
drivers/i2c/busses/i2c-ali1535.c
drivers/i2c/busses/i2c-ali1535.c
+2
-8
drivers/i2c/busses/i2c-ali15x3.c
drivers/i2c/busses/i2c-ali15x3.c
+3
-10
drivers/i2c/busses/i2c-amd756.c
drivers/i2c/busses/i2c-amd756.c
+3
-11
drivers/i2c/busses/i2c-amd8111.c
drivers/i2c/busses/i2c-amd8111.c
+1
-2
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-i801.c
+3
-11
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-nforce2.c
+426
-0
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-piix4.c
+1
-9
drivers/i2c/busses/i2c-sis96x.c
drivers/i2c/busses/i2c-sis96x.c
+1
-8
drivers/i2c/busses/i2c-viapro.c
drivers/i2c/busses/i2c-viapro.c
+1
-8
drivers/i2c/chips/via686a.c
drivers/i2c/chips/via686a.c
+5
-5
drivers/i2c/i2c-keywest.c
drivers/i2c/i2c-keywest.c
+16
-74
include/linux/i2c.h
include/linux/i2c.h
+7
-0
No files found.
drivers/i2c/Kconfig
View file @
6fd6bef3
...
...
@@ -20,9 +20,7 @@ config I2C
interfaces", below.
If you want I2C support, you should say Y here and also to the
specific driver for your bus adapter(s) below. If you say Y to
"/proc file system" below, you will then get a /proc interface which
is documented in <file:Documentation/i2c/proc-interface>.
specific driver for your bus adapter(s) below.
This I2C support is also available as a module. If you want to
compile it as a module, say M here and read
...
...
drivers/i2c/busses/Kconfig
View file @
6fd6bef3
...
...
@@ -108,6 +108,23 @@ config I2C_ISA
in the lm_sensors package, which you can download at
http://www.lm-sensors.nu
config I2C_NFORCE2
tristate " Nvidia Nforce2"
depends on I2C && PCI && EXPERIMENTAL
help
If you say yes to this option, support will be included for the Nvidia
Nforce2 family of mainboard I2C interfaces.
This can also be built as a module which can be inserted and removed
while the kernel is running. If you want to compile it as a module,
say M here and read <file:Documentation/modules.txt>.
The module will be called i2c-nforce2.
You will also need the latest user-space utilties: you can find them
in the lm_sensors package, which you can download at
http://www.lm-sensors.nu
config I2C_PIIX4
tristate " Intel PIIX4"
...
...
drivers/i2c/busses/Makefile
View file @
6fd6bef3
...
...
@@ -8,6 +8,7 @@ obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o
obj-$(CONFIG_I2C_AMD8111)
+=
i2c-amd8111.o
obj-$(CONFIG_I2C_I801)
+=
i2c-i801.o
obj-$(CONFIG_I2C_ISA)
+=
i2c-isa.o
obj-$(CONFIG_I2C_NFORCE2)
+=
i2c-nforce2.o
obj-$(CONFIG_I2C_PIIX4)
+=
i2c-piix4.o
obj-$(CONFIG_I2C_SIS96X)
+=
i2c-sis96x.o
obj-$(CONFIG_I2C_VIAPRO)
+=
i2c-viapro.o
drivers/i2c/busses/i2c-ali1535.c
View file @
6fd6bef3
...
...
@@ -206,12 +206,6 @@ static int ali1535_setup(struct pci_dev *dev)
return
retval
;
}
static
void
ali1535_do_pause
(
unsigned
int
amount
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
amount
);
}
static
int
ali1535_transaction
(
struct
i2c_adapter
*
adap
)
{
int
temp
;
...
...
@@ -283,7 +277,7 @@ static int ali1535_transaction(struct i2c_adapter *adap)
/* We will always wait for a fraction of a second! */
timeout
=
0
;
do
{
ali1535_do_pause
(
1
);
i2c_delay
(
1
);
temp
=
inb_p
(
SMBHSTSTS
);
}
while
(((
temp
&
ALI1535_STS_BUSY
)
&&
!
(
temp
&
ALI1535_STS_IDLE
))
&&
(
timeout
++
<
MAX_TIMEOUT
));
...
...
@@ -357,7 +351,7 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
for
(
timeout
=
0
;
(
timeout
<
MAX_TIMEOUT
)
&&
!
(
temp
&
ALI1535_STS_IDLE
);
timeout
++
)
{
ali1535_do_pause
(
1
);
i2c_delay
(
1
);
temp
=
inb_p
(
SMBHSTSTS
);
}
if
(
timeout
>=
MAX_TIMEOUT
)
...
...
drivers/i2c/busses/i2c-ali15x3.c
View file @
6fd6bef3
...
...
@@ -225,13 +225,6 @@ static int ali15x3_setup(struct pci_dev *ALI15X3_dev)
return
-
ENODEV
;
}
/* Internally used pause function */
static
void
ali15x3_do_pause
(
unsigned
int
amount
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
amount
);
}
/* Another internally used function */
static
int
ali15x3_transaction
(
struct
i2c_adapter
*
adap
)
{
...
...
@@ -304,7 +297,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
/* We will always wait for a fraction of a second! */
timeout
=
0
;
do
{
ali15x3_do_pause
(
1
);
i2c_delay
(
1
);
temp
=
inb_p
(
SMBHSTSTS
);
}
while
((
!
(
temp
&
(
ALI15X3_STS_ERR
|
ALI15X3_STS_DONE
)))
&&
(
timeout
++
<
MAX_TIMEOUT
));
...
...
@@ -361,7 +354,7 @@ static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
for
(
timeout
=
0
;
(
timeout
<
MAX_TIMEOUT
)
&&
!
(
temp
&
ALI15X3_STS_IDLE
);
timeout
++
)
{
ali15x3_do_pause
(
1
);
i2c_delay
(
1
);
temp
=
inb_p
(
SMBHSTSTS
);
}
if
(
timeout
>=
MAX_TIMEOUT
)
{
...
...
@@ -515,6 +508,7 @@ static int __devinit ali15x3_probe(struct pci_dev *dev, const struct pci_device_
static
void
__devexit
ali15x3_remove
(
struct
pci_dev
*
dev
)
{
i2c_del_adapter
(
&
ali15x3_adapter
);
release_region
(
ali15x3_smba
,
ALI15X3_SMB_IOSIZE
);
}
static
struct
pci_driver
ali15x3_driver
=
{
...
...
@@ -533,7 +527,6 @@ static int __init i2c_ali15x3_init(void)
static
void
__exit
i2c_ali15x3_exit
(
void
)
{
pci_unregister_driver
(
&
ali15x3_driver
);
release_region
(
ali15x3_smba
,
ALI15X3_SMB_IOSIZE
);
}
MODULE_AUTHOR
(
"Frodo Looijaard <frodol@dds.nl>, "
...
...
drivers/i2c/busses/i2c-amd756.c
View file @
6fd6bef3
...
...
@@ -93,14 +93,6 @@ static unsigned short amd756_ioport = 0;
see E0 for the status bits and enabled in E2
*/
/* Internally used pause function */
static
void
amd756_do_pause
(
unsigned
int
amount
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
amount
);
}
#define GS_ABRT_STS (1 << 0)
#define GS_COL_STS (1 << 1)
#define GS_PRERR_STS (1 << 2)
...
...
@@ -132,7 +124,7 @@ static int amd756_transaction(struct i2c_adapter *adap)
if
((
temp
=
inw_p
(
SMB_GLOBAL_STATUS
))
&
(
GS_HST_STS
|
GS_SMB_STS
))
{
dev_dbg
(
&
adap
->
dev
,
": SMBus busy (%04x). Waiting...
\n
"
,
temp
);
do
{
amd756_do_pause
(
1
);
i2c_delay
(
1
);
temp
=
inw_p
(
SMB_GLOBAL_STATUS
);
}
while
((
temp
&
(
GS_HST_STS
|
GS_SMB_STS
))
&&
(
timeout
++
<
MAX_TIMEOUT
));
...
...
@@ -149,7 +141,7 @@ static int amd756_transaction(struct i2c_adapter *adap)
/* We will always wait for a fraction of a second! */
do
{
amd756_do_pause
(
1
);
i2c_delay
(
1
);
temp
=
inw_p
(
SMB_GLOBAL_STATUS
);
}
while
((
temp
&
GS_HST_STS
)
&&
(
timeout
++
<
MAX_TIMEOUT
));
...
...
@@ -196,7 +188,7 @@ static int amd756_transaction(struct i2c_adapter *adap)
abort:
dev_warn
(
&
adap
->
dev
,
": Sending abort.
\n
"
);
outw_p
(
inw
(
SMB_GLOBAL_ENABLE
)
|
GE_ABORT
,
SMB_GLOBAL_ENABLE
);
amd756_do_pause
(
100
);
i2c_delay
(
100
);
outw_p
(
GS_CLEAR_STS
,
SMB_GLOBAL_STATUS
);
return
-
1
;
}
...
...
drivers/i2c/busses/i2c-amd8111.c
View file @
6fd6bef3
...
...
@@ -275,8 +275,7 @@ s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
}
if
(
~
temp
[
0
]
&
AMD_SMB_STS_DONE
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
HZ
/
100
);
i2c_delay
(
HZ
/
100
);
amd_ec_read
(
smbus
,
AMD_SMB_STS
,
temp
+
0
);
}
...
...
drivers/i2c/busses/i2c-i801.c
View file @
6fd6bef3
...
...
@@ -103,7 +103,6 @@ MODULE_PARM_DESC(force_addr,
"Forcibly enable the I801 at the given address. "
"EXTREMELY DANGEROUS!"
);
static
void
i801_do_pause
(
unsigned
int
amount
);
static
int
i801_transaction
(
void
);
static
int
i801_block_transaction
(
union
i2c_smbus_data
*
data
,
char
read_write
,
int
command
);
...
...
@@ -178,13 +177,6 @@ static int i801_setup(struct pci_dev *dev)
return
error_return
;
}
static
void
i801_do_pause
(
unsigned
int
amount
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
amount
);
}
static
int
i801_transaction
(
void
)
{
int
temp
;
...
...
@@ -214,7 +206,7 @@ static int i801_transaction(void)
/* We will always wait for a fraction of a second! */
do
{
i
801_do_pause
(
1
);
i
2c_delay
(
1
);
temp
=
inb_p
(
SMBHSTSTS
);
}
while
((
temp
&
0x01
)
&&
(
timeout
++
<
MAX_TIMEOUT
));
...
...
@@ -342,7 +334,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
timeout
=
0
;
do
{
temp
=
inb_p
(
SMBHSTSTS
);
i
801_do_pause
(
1
);
i
2c_delay
(
1
);
}
while
((
!
(
temp
&
0x80
))
&&
(
timeout
++
<
MAX_TIMEOUT
));
...
...
@@ -402,7 +394,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
timeout
=
0
;
do
{
temp
=
inb_p
(
SMBHSTSTS
);
i
801_do_pause
(
1
);
i
2c_delay
(
1
);
}
while
((
!
(
temp
&
0x02
))
&&
(
timeout
++
<
MAX_TIMEOUT
));
...
...
drivers/i2c/busses/i2c-nforce2.c
0 → 100644
View file @
6fd6bef3
/*
SMBus driver for nVidia nForce2 MCP
Ported to 2.5 Patrick Dreker <patrick@dreker.de>,
Copyright (c) 2003 Hans-Frieder Vogt <hfvogt@arcor.de>,
Based on
SMBus 2.0 driver for AMD-8111 IO-Hub
Copyright (c) 2002 Vojtech Pavlik
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.
*/
/*
SUPPORTED DEVICES PCI ID
nForce2 MCP 0064
This driver supports the 2 SMBuses that are included in the MCP2 of the
nForce2 chipset.
*/
/* Note: we assume there can only be one nForce2, with two SMBus interfaces */
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <asm/io.h>
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Hans-Frieder Vogt <hfvogt@arcor.de>"
);
MODULE_DESCRIPTION
(
"nForce2 SMBus driver"
);
#ifndef PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS
#define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064
#endif
/* TODO: sync with lm-sensors */
#ifndef I2C_HW_SMBUS_NFORCE2
#define I2C_HW_SMBUS_NFORCE2 0x0c
#endif
struct
nforce2_smbus
{
struct
pci_dev
*
dev
;
struct
i2c_adapter
adapter
;
int
base
;
int
size
;
};
/*
* nVidia nForce2 SMBus control register definitions
*/
#define NFORCE_PCI_SMB1 0x50
#define NFORCE_PCI_SMB2 0x54
/*
* ACPI 2.0 chapter 13 SMBus 2.0 EC register model
*/
#define NVIDIA_SMB_PRTCL (smbus->base + 0x00)
/* protocol, PEC */
#define NVIDIA_SMB_STS (smbus->base + 0x01)
/* status */
#define NVIDIA_SMB_ADDR (smbus->base + 0x02)
/* address */
#define NVIDIA_SMB_CMD (smbus->base + 0x03)
/* command */
#define NVIDIA_SMB_DATA (smbus->base + 0x04)
/* 32 data registers */
#define NVIDIA_SMB_BCNT (smbus->base + 0x24)
/* number of data bytes */
#define NVIDIA_SMB_ALRM_A (smbus->base + 0x25)
/* alarm address */
#define NVIDIA_SMB_ALRM_D (smbus->base + 0x26)
/* 2 bytes alarm data */
#define NVIDIA_SMB_STS_DONE 0x80
#define NVIDIA_SMB_STS_ALRM 0x40
#define NVIDIA_SMB_STS_RES 0x20
#define NVIDIA_SMB_STS_STATUS 0x1f
#define NVIDIA_SMB_PRTCL_WRITE 0x00
#define NVIDIA_SMB_PRTCL_READ 0x01
#define NVIDIA_SMB_PRTCL_QUICK 0x02
#define NVIDIA_SMB_PRTCL_BYTE 0x04
#define NVIDIA_SMB_PRTCL_BYTE_DATA 0x06
#define NVIDIA_SMB_PRTCL_WORD_DATA 0x08
#define NVIDIA_SMB_PRTCL_BLOCK_DATA 0x0a
#define NVIDIA_SMB_PRTCL_PROC_CALL 0x0c
#define NVIDIA_SMB_PRTCL_BLOCK_PROC_CALL 0x0d
#define NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA 0x4a
#define NVIDIA_SMB_PRTCL_PEC 0x80
/* Other settings */
#define MAX_TIMEOUT 256
static
s32
nforce2_access
(
struct
i2c_adapter
*
adap
,
u16
addr
,
unsigned
short
flags
,
char
read_write
,
u8
command
,
int
size
,
union
i2c_smbus_data
*
data
);
static
u32
nforce2_func
(
struct
i2c_adapter
*
adapter
);
static
struct
i2c_algorithm
smbus_algorithm
=
{
.
name
=
"Non-I2C SMBus adapter"
,
.
id
=
I2C_ALGO_SMBUS
,
.
smbus_xfer
=
nforce2_access
,
.
functionality
=
nforce2_func
,
};
static
struct
i2c_adapter
nforce2_adapter
=
{
.
owner
=
THIS_MODULE
,
.
id
=
I2C_ALGO_SMBUS
|
I2C_HW_SMBUS_NFORCE2
,
.
class
=
I2C_ADAP_CLASS_SMBUS
,
.
algo
=
&
smbus_algorithm
,
.
dev
=
{
.
name
=
"unset"
,
},
};
#if 0
/* Internally used pause function */
static void nforce2_do_pause(unsigned int amount)
{
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(amount);
}
#endif
/* Return -1 on error. See smbus.h for more information */
static
s32
nforce2_access
(
struct
i2c_adapter
*
adap
,
u16
addr
,
unsigned
short
flags
,
char
read_write
,
u8
command
,
int
size
,
union
i2c_smbus_data
*
data
)
{
struct
nforce2_smbus
*
smbus
=
adap
->
algo_data
;
unsigned
char
protocol
,
pec
,
temp
;
unsigned
char
len
=
0
;
/* to keep the compiler quiet */
int
timeout
=
0
;
int
i
;
protocol
=
(
read_write
==
I2C_SMBUS_READ
)
?
NVIDIA_SMB_PRTCL_READ
:
NVIDIA_SMB_PRTCL_WRITE
;
pec
=
(
flags
&
I2C_CLIENT_PEC
)
?
NVIDIA_SMB_PRTCL_PEC
:
0
;
switch
(
size
)
{
case
I2C_SMBUS_QUICK
:
protocol
|=
NVIDIA_SMB_PRTCL_QUICK
;
read_write
=
I2C_SMBUS_WRITE
;
break
;
case
I2C_SMBUS_BYTE
:
if
(
read_write
==
I2C_SMBUS_WRITE
)
outb_p
(
data
->
byte
,
NVIDIA_SMB_DATA
);
protocol
|=
NVIDIA_SMB_PRTCL_BYTE
;
break
;
case
I2C_SMBUS_BYTE_DATA
:
outb_p
(
command
,
NVIDIA_SMB_CMD
);
if
(
read_write
==
I2C_SMBUS_WRITE
)
outb_p
(
data
->
byte
,
NVIDIA_SMB_DATA
);
protocol
|=
NVIDIA_SMB_PRTCL_BYTE_DATA
;
break
;
case
I2C_SMBUS_WORD_DATA
:
outb_p
(
command
,
NVIDIA_SMB_CMD
);
if
(
read_write
==
I2C_SMBUS_WRITE
)
{
outb_p
(
data
->
word
,
NVIDIA_SMB_DATA
);
outb_p
(
data
->
word
>>
8
,
NVIDIA_SMB_DATA
+
1
);
}
protocol
|=
NVIDIA_SMB_PRTCL_WORD_DATA
|
pec
;
break
;
case
I2C_SMBUS_BLOCK_DATA
:
outb_p
(
command
,
NVIDIA_SMB_CMD
);
if
(
read_write
==
I2C_SMBUS_WRITE
)
{
len
=
min_t
(
u8
,
data
->
block
[
0
],
32
);
outb_p
(
len
,
NVIDIA_SMB_BCNT
);
for
(
i
=
0
;
i
<
len
;
i
++
)
outb_p
(
data
->
block
[
i
+
1
],
NVIDIA_SMB_DATA
+
i
);
}
protocol
|=
NVIDIA_SMB_PRTCL_BLOCK_DATA
|
pec
;
break
;
case
I2C_SMBUS_I2C_BLOCK_DATA
:
len
=
min_t
(
u8
,
data
->
block
[
0
],
32
);
outb_p
(
command
,
NVIDIA_SMB_CMD
);
outb_p
(
len
,
NVIDIA_SMB_BCNT
);
if
(
read_write
==
I2C_SMBUS_WRITE
)
for
(
i
=
0
;
i
<
len
;
i
++
)
outb_p
(
data
->
block
[
i
+
1
],
NVIDIA_SMB_DATA
+
i
);
protocol
|=
NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA
;
break
;
case
I2C_SMBUS_PROC_CALL
:
dev_err
(
&
adap
->
dev
,
"I2C_SMBUS_PROC_CALL not supported!
\n
"
);
return
-
1
;
/*
outb_p(command, NVIDIA_SMB_CMD);
outb_p(data->word, NVIDIA_SMB_DATA);
outb_p(data->word >> 8, NVIDIA_SMB_DATA + 1);
protocol = NVIDIA_SMB_PRTCL_PROC_CALL | pec;
read_write = I2C_SMBUS_READ;
break;
*/
case
I2C_SMBUS_BLOCK_PROC_CALL
:
dev_err
(
&
adap
->
dev
,
"I2C_SMBUS_BLOCK_PROC_CALL not supported!
\n
"
);
return
-
1
;
/*
protocol |= pec;
len = min_t(u8, data->block[0], 31);
outb_p(command, NVIDIA_SMB_CMD);
outb_p(len, NVIDIA_SMB_BCNT);
for (i = 0; i < len; i++)
outb_p(data->block[i + 1], NVIDIA_SMB_DATA + i);
protocol = NVIDIA_SMB_PRTCL_BLOCK_PROC_CALL | pec;
read_write = I2C_SMBUS_READ;
break;
*/
case
I2C_SMBUS_WORD_DATA_PEC
:
case
I2C_SMBUS_BLOCK_DATA_PEC
:
case
I2C_SMBUS_PROC_CALL_PEC
:
case
I2C_SMBUS_BLOCK_PROC_CALL_PEC
:
dev_err
(
&
adap
->
dev
,
"Unexpected software PEC transaction %d
\n
."
,
size
);
return
-
1
;
default:
dev_err
(
&
adap
->
dev
,
"Unsupported transaction %d
\n
"
,
size
);
return
-
1
;
}
outb_p
((
addr
&
0x7f
)
<<
1
,
NVIDIA_SMB_ADDR
);
outb_p
(
protocol
,
NVIDIA_SMB_PRTCL
);
temp
=
inb_p
(
NVIDIA_SMB_STS
);
#if 0
do {
nforce2_do_pause(1);
temp = inb_p(NVIDIA_SMB_STS);
} while (((temp & NVIDIA_SMB_STS_DONE) == 0) && (timeout++ < MAX_TIMEOUT));
#endif
if
(
~
temp
&
NVIDIA_SMB_STS_DONE
)
{
udelay
(
500
);
temp
=
inb_p
(
NVIDIA_SMB_STS
);
}
if
(
~
temp
&
NVIDIA_SMB_STS_DONE
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
HZ
/
100
);
temp
=
inb_p
(
NVIDIA_SMB_STS
);
}
if
((
timeout
>=
MAX_TIMEOUT
)
||
(
~
temp
&
NVIDIA_SMB_STS_DONE
)
||
(
temp
&
NVIDIA_SMB_STS_STATUS
))
return
-
1
;
if
(
read_write
==
I2C_SMBUS_WRITE
)
return
0
;
switch
(
size
)
{
case
I2C_SMBUS_BYTE
:
case
I2C_SMBUS_BYTE_DATA
:
data
->
byte
=
inb_p
(
NVIDIA_SMB_DATA
);
break
;
case
I2C_SMBUS_WORD_DATA
:
/* case I2C_SMBUS_PROC_CALL: not supported */
data
->
word
=
inb_p
(
NVIDIA_SMB_DATA
)
|
(
inb_p
(
NVIDIA_SMB_DATA
+
1
)
<<
8
);
break
;
case
I2C_SMBUS_BLOCK_DATA
:
/* case I2C_SMBUS_BLOCK_PROC_CALL: not supported */
len
=
inb_p
(
NVIDIA_SMB_BCNT
);
len
=
min_t
(
u8
,
len
,
32
);
case
I2C_SMBUS_I2C_BLOCK_DATA
:
for
(
i
=
0
;
i
<
len
;
i
++
)
data
->
block
[
i
+
1
]
=
inb_p
(
NVIDIA_SMB_DATA
+
i
);
data
->
block
[
0
]
=
len
;
break
;
}
return
0
;
}
static
u32
nforce2_func
(
struct
i2c_adapter
*
adapter
)
{
/* other functionality might be possible, but is not tested */
return
I2C_FUNC_SMBUS_QUICK
|
I2C_FUNC_SMBUS_BYTE
|
I2C_FUNC_SMBUS_BYTE_DATA
|
I2C_FUNC_SMBUS_WORD_DATA
/* |
I2C_FUNC_SMBUS_BLOCK_DATA */
;
}
static
struct
pci_device_id
nforce2_ids
[]
=
{
{
PCI_VENDOR_ID_NVIDIA
,
PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0
}
};
static
int
__devinit
nforce2_probe_smb
(
struct
pci_dev
*
dev
,
int
reg
,
struct
nforce2_smbus
*
smbus
,
char
*
name
)
{
u16
iobase
;
int
error
;
if
(
pci_read_config_word
(
dev
,
reg
,
&
iobase
)
!=
PCIBIOS_SUCCESSFUL
)
{
dev_err
(
&
smbus
->
adapter
.
dev
,
"Error reading PCI config for %s
\n
"
,
name
);
return
-
1
;
}
smbus
->
dev
=
dev
;
smbus
->
base
=
iobase
&
0xfffc
;
smbus
->
size
=
8
;
if
(
!
request_region
(
smbus
->
base
,
smbus
->
size
,
"nForce2 SMBus"
))
{
dev_err
(
&
smbus
->
adapter
.
dev
,
"Error requesting region %02x .. %02X for %s
\n
"
,
smbus
->
base
,
smbus
->
base
+
smbus
->
size
-
1
,
name
);
return
-
1
;
}
/*
smbus->adapter.owner = THIS_MODULE;
smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2;
smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus;
*/
smbus
->
adapter
=
nforce2_adapter
;
smbus
->
adapter
.
dev
.
parent
=
&
dev
->
dev
;
snprintf
(
smbus
->
adapter
.
dev
.
name
,
DEVICE_NAME_SIZE
,
"SMBus nForce2 adapter at %04x"
,
smbus
->
base
);
error
=
i2c_add_adapter
(
&
smbus
->
adapter
);
if
(
error
)
{
dev_err
(
&
smbus
->
adapter
.
dev
,
"Failed to register adapter.
\n
"
);
release_region
(
smbus
->
base
,
smbus
->
size
);
return
-
1
;
}
dev_info
(
&
smbus
->
adapter
.
dev
,
"nForce2 SMBus adapter at %#x
\n
"
,
smbus
->
base
);
return
0
;
}
static
int
__devinit
nforce2_probe
(
struct
pci_dev
*
dev
,
const
struct
pci_device_id
*
id
)
{
struct
nforce2_smbus
*
smbuses
;
int
res1
,
res2
;
/* we support 2 SMBus adapters */
if
(
!
(
smbuses
=
(
void
*
)
kmalloc
(
2
*
sizeof
(
struct
nforce2_smbus
),
GFP_KERNEL
)))
return
-
ENOMEM
;
memset
(
smbuses
,
0
,
2
*
sizeof
(
struct
nforce2_smbus
));
pci_set_drvdata
(
dev
,
smbuses
);
/* SMBus adapter 1 */
res1
=
nforce2_probe_smb
(
dev
,
NFORCE_PCI_SMB1
,
&
smbuses
[
0
],
"SMB1"
);
if
(
res1
<
0
)
{
dev_err
(
&
dev
->
dev
,
"Error probing SMB1.
\n
"
);
smbuses
[
0
].
base
=
0
;
/* to have a check value */
}
res2
=
nforce2_probe_smb
(
dev
,
NFORCE_PCI_SMB2
,
&
smbuses
[
1
],
"SMB2"
);
if
(
res2
<
0
)
{
dev_err
(
&
dev
->
dev
,
"Error probing SMB2.
\n
"
);
smbuses
[
1
].
base
=
0
;
/* to have a check value */
}
if
((
res1
<
0
)
&&
(
res2
<
0
))
{
/* we did not find even one of the SMBuses, so we give up */
kfree
(
smbuses
);
return
-
ENODEV
;
}
return
0
;
}
static
void
__devexit
nforce2_remove
(
struct
pci_dev
*
dev
)
{
struct
nforce2_smbus
*
smbuses
=
(
void
*
)
pci_get_drvdata
(
dev
);
if
(
smbuses
[
0
].
base
)
{
i2c_del_adapter
(
&
smbuses
[
0
].
adapter
);
release_region
(
smbuses
[
0
].
base
,
smbuses
[
0
].
size
);
}
if
(
smbuses
[
1
].
base
)
{
i2c_del_adapter
(
&
smbuses
[
1
].
adapter
);
release_region
(
smbuses
[
1
].
base
,
smbuses
[
1
].
size
);
}
kfree
(
smbuses
);
}
static
struct
pci_driver
nforce2_driver
=
{
.
name
=
"nForce2 SMBus"
,
.
id_table
=
nforce2_ids
,
.
probe
=
nforce2_probe
,
.
remove
=
__devexit_p
(
nforce2_remove
),
};
static
int
__init
nforce2_init
(
void
)
{
return
pci_module_init
(
&
nforce2_driver
);
}
static
void
__exit
nforce2_exit
(
void
)
{
pci_unregister_driver
(
&
nforce2_driver
);
}
module_init
(
nforce2_init
);
module_exit
(
nforce2_exit
);
drivers/i2c/busses/i2c-piix4.c
View file @
6fd6bef3
...
...
@@ -99,7 +99,6 @@ MODULE_PARM_DESC(force_addr,
"Forcibly enable the PIIX4 at the given address. "
"EXTREMELY DANGEROUS!"
);
static
void
piix4_do_pause
(
unsigned
int
amount
);
static
int
piix4_transaction
(
void
);
...
...
@@ -208,13 +207,6 @@ static int piix4_setup(struct pci_dev *PIIX4_dev, const struct pci_device_id *id
return
error_return
;
}
/* Internally used pause function */
static
void
piix4_do_pause
(
unsigned
int
amount
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
amount
);
}
/* Another internally used function */
static
int
piix4_transaction
(
void
)
{
...
...
@@ -245,7 +237,7 @@ static int piix4_transaction(void)
/* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
do
{
piix4_do_pause
(
1
);
i2c_delay
(
1
);
temp
=
inb_p
(
SMBHSTSTS
);
}
while
((
temp
&
0x01
)
&&
(
timeout
++
<
MAX_TIMEOUT
));
...
...
drivers/i2c/busses/i2c-sis96x.c
View file @
6fd6bef3
...
...
@@ -99,13 +99,6 @@ static inline void sis96x_write(u8 reg, u8 data)
outb
(
data
,
sis96x_smbus_base
+
reg
)
;
}
/* Internally used pause function */
static
void
sis96x_do_pause
(
unsigned
int
amount
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
amount
);
}
/* Execute a SMBus transaction.
int size is from SIS96x_QUICK to SIS96x_BLOCK_DATA
*/
...
...
@@ -147,7 +140,7 @@ static int sis96x_transaction(int size)
/* We will always wait for a fraction of a second! */
do
{
sis96x_do_pause
(
1
);
i2c_delay
(
1
);
temp
=
sis96x_read
(
SMB_STS
);
}
while
(
!
(
temp
&
0x0e
)
&&
(
timeout
++
<
MAX_TIMEOUT
));
...
...
drivers/i2c/busses/i2c-viapro.c
View file @
6fd6bef3
...
...
@@ -103,13 +103,6 @@ MODULE_PARM_DESC(force_addr,
static
struct
i2c_adapter
vt596_adapter
;
/* Internally used pause function */
static
void
vt596_do_pause
(
unsigned
int
amount
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
amount
);
}
/* Another internally used function */
static
int
vt596_transaction
(
void
)
{
...
...
@@ -143,7 +136,7 @@ static int vt596_transaction(void)
/* We will always wait for a fraction of a second!
I don't know if VIA needs this, Intel did */
do
{
vt596_do_pause
(
1
);
i2c_delay
(
1
);
temp
=
inb_p
(
SMBHSTSTS
);
}
while
((
temp
&
0x01
)
&&
(
timeout
++
<
MAX_TIMEOUT
));
...
...
drivers/i2c/chips/via686a.c
View file @
6fd6bef3
...
...
@@ -494,27 +494,27 @@ static ssize_t show_temp(struct device *dev, char *buf, int nr) {
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
via686a_data
*
data
=
i2c_get_clientdata
(
client
);
via686a_update_client
(
client
);
return
sprintf
(
buf
,
"%ld
\n
"
,
TEMP_FROM_REG10
(
data
->
temp
[
nr
])
*
10
);
return
sprintf
(
buf
,
"%ld
\n
"
,
TEMP_FROM_REG10
(
data
->
temp
[
nr
])
*
10
0
);
}
/* more like overshoot temperature */
static
ssize_t
show_temp_max
(
struct
device
*
dev
,
char
*
buf
,
int
nr
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
via686a_data
*
data
=
i2c_get_clientdata
(
client
);
via686a_update_client
(
client
);
return
sprintf
(
buf
,
"%ld
\n
"
,
TEMP_FROM_REG
(
data
->
temp_over
[
nr
])
*
10
);
return
sprintf
(
buf
,
"%ld
\n
"
,
TEMP_FROM_REG
(
data
->
temp_over
[
nr
])
*
10
0
);
}
/* more like hysteresis temperature */
static
ssize_t
show_temp_min
(
struct
device
*
dev
,
char
*
buf
,
int
nr
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
via686a_data
*
data
=
i2c_get_clientdata
(
client
);
via686a_update_client
(
client
);
return
sprintf
(
buf
,
"%ld
\n
"
,
TEMP_FROM_REG
(
data
->
temp_hyst
[
nr
])
*
10
);
return
sprintf
(
buf
,
"%ld
\n
"
,
TEMP_FROM_REG
(
data
->
temp_hyst
[
nr
])
*
10
0
);
}
static
ssize_t
set_temp_max
(
struct
device
*
dev
,
const
char
*
buf
,
size_t
count
,
int
nr
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
via686a_data
*
data
=
i2c_get_clientdata
(
client
);
int
val
=
simple_strtol
(
buf
,
NULL
,
10
)
/
10
;
int
val
=
simple_strtol
(
buf
,
NULL
,
10
)
/
10
0
;
data
->
temp_over
[
nr
]
=
TEMP_TO_REG
(
val
);
via686a_write_value
(
client
,
VIA686A_REG_TEMP_OVER
(
nr
),
data
->
temp_over
[
nr
]);
return
count
;
...
...
@@ -523,7 +523,7 @@ static ssize_t set_temp_min(struct device *dev, const char *buf,
size_t
count
,
int
nr
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
via686a_data
*
data
=
i2c_get_clientdata
(
client
);
int
val
=
simple_strtol
(
buf
,
NULL
,
10
)
/
10
;
int
val
=
simple_strtol
(
buf
,
NULL
,
10
)
/
10
0
;
data
->
temp_hyst
[
nr
]
=
TEMP_TO_REG
(
val
);
via686a_write_value
(
client
,
VIA686A_REG_TEMP_HYST
(
nr
),
data
->
temp_hyst
[
nr
]);
return
count
;
...
...
drivers/i2c/i2c-keywest.c
View file @
6fd6bef3
...
...
@@ -66,8 +66,6 @@
#include "i2c-keywest.h"
#undef POLLED_MODE
#define DBG(x...) do {\
if (debug > 0) \
printk(KERN_DEBUG "KW:" x); \
...
...
@@ -85,27 +83,6 @@ int debug = 0;
static
struct
keywest_iface
*
ifaces
=
NULL
;
#ifdef POLLED_MODE
/* This isn't fast, but will go once I implement interrupt with
* proper timeout
*/
static
u8
wait_interrupt
(
struct
keywest_iface
*
iface
)
{
int
i
;
u8
isr
;
for
(
i
=
0
;
i
<
POLL_TIMEOUT
;
i
++
)
{
isr
=
read_reg
(
reg_isr
)
&
KW_I2C_IRQ_MASK
;
if
(
isr
!=
0
)
return
isr
;
current
->
state
=
TASK_UNINTERRUPTIBLE
;
schedule_timeout
(
1
);
}
return
isr
;
}
#endif
/* POLLED_MODE */
static
void
do_stop
(
struct
keywest_iface
*
iface
,
int
result
)
...
...
@@ -116,16 +93,17 @@ do_stop(struct keywest_iface* iface, int result)
}
/* Main state machine for standard & standard sub mode */
static
void
static
int
handle_interrupt
(
struct
keywest_iface
*
iface
,
u8
isr
)
{
int
ack
;
int
rearm_timer
=
1
;
DBG
(
"handle_interrupt(), got: %x, status: %x, state: %d
\n
"
,
isr
,
read_reg
(
reg_status
),
iface
->
state
);
if
(
isr
==
0
&&
iface
->
state
!=
state_stop
)
{
do_stop
(
iface
,
-
1
);
return
;
return
rearm_timer
;
}
if
(
isr
&
KW_I2C_IRQ_STOP
&&
iface
->
state
!=
state_stop
)
{
iface
->
result
=
-
1
;
...
...
@@ -196,20 +174,19 @@ handle_interrupt(struct keywest_iface *iface, u8 isr)
if
(
!
(
isr
&
KW_I2C_IRQ_STOP
)
&&
(
++
iface
->
stopretry
)
<
10
)
do_stop
(
iface
,
-
1
);
else
{
rearm_timer
=
0
;
iface
->
state
=
state_idle
;
write_reg
(
reg_control
,
0x00
);
write_reg
(
reg_ier
,
0x00
);
#ifndef POLLED_MODE
complete
(
&
iface
->
complete
);
#endif
/* POLLED_MODE */
}
break
;
}
write_reg
(
reg_isr
,
isr
);
}
#ifndef POLLED_MODE
return
rearm_timer
;
}
/* Interrupt handler */
static
irqreturn_t
...
...
@@ -219,11 +196,8 @@ keywest_irq(int irq, void *dev_id, struct pt_regs *regs)
spin_lock
(
&
iface
->
lock
);
del_timer
(
&
iface
->
timeout_timer
);
handle_interrupt
(
iface
,
read_reg
(
reg_isr
));
if
(
iface
->
state
!=
state_idle
)
{
iface
->
timeout_timer
.
expires
=
jiffies
+
POLL_TIMEOUT
;
add_timer
(
&
iface
->
timeout_timer
);
}
if
(
handle_interrupt
(
iface
,
read_reg
(
reg_isr
)))
mod_timer
(
&
iface
->
timeout_timer
,
jiffies
+
POLL_TIMEOUT
);
spin_unlock
(
&
iface
->
lock
);
return
IRQ_HANDLED
;
}
...
...
@@ -235,16 +209,11 @@ keywest_timeout(unsigned long data)
DBG
(
"timeout !
\n
"
);
spin_lock_irq
(
&
iface
->
lock
);
handle_interrupt
(
iface
,
read_reg
(
reg_isr
));
if
(
iface
->
state
!=
state_idle
)
{
iface
->
timeout_timer
.
expires
=
jiffies
+
POLL_TIMEOUT
;
add_timer
(
&
iface
->
timeout_timer
);
}
if
(
handle_interrupt
(
iface
,
read_reg
(
reg_isr
)))
mod_timer
(
&
iface
->
timeout_timer
,
jiffies
+
POLL_TIMEOUT
);
spin_unlock
(
&
iface
->
lock
);
}
#endif
/* POLLED_MODE */
/*
* SMBUS-type transfer entrypoint
*/
...
...
@@ -331,24 +300,13 @@ keywest_smbus_xfer( struct i2c_adapter* adap,
write_reg
(
reg_subaddr
,
command
);
/* Arm timeout */
iface
->
timeout_timer
.
expires
=
jiffies
+
POLL_TIMEOUT
;
add_timer
(
&
iface
->
timeout_timer
);
mod_timer
(
&
iface
->
timeout_timer
,
jiffies
+
POLL_TIMEOUT
);
/* Start sending address & enable interrupt*/
write_reg
(
reg_control
,
read_reg
(
reg_control
)
|
KW_I2C_CTL_XADDR
);
write_reg
(
reg_ier
,
KW_I2C_IRQ_MASK
);
#ifdef POLLED_MODE
DBG
(
"using polled mode...
\n
"
);
/* State machine, to turn into an interrupt handler */
while
(
iface
->
state
!=
state_idle
)
{
u8
isr
=
wait_interrupt
(
iface
);
handle_interrupt
(
iface
,
isr
);
}
#else
/* POLLED_MODE */
DBG
(
"using interrupt mode...
\n
"
);
wait_for_completion
(
&
iface
->
complete
);
#endif
/* POLLED_MODE */
rc
=
iface
->
result
;
DBG
(
"transfer done, result: %d
\n
"
,
rc
);
...
...
@@ -421,24 +379,13 @@ keywest_xfer( struct i2c_adapter *adap,
((
iface
->
read_write
==
I2C_SMBUS_READ
)
?
0x01
:
0x00
));
/* Arm timeout */
iface
->
timeout_timer
.
expires
=
jiffies
+
POLL_TIMEOUT
;
add_timer
(
&
iface
->
timeout_timer
);
mod_timer
(
&
iface
->
timeout_timer
,
jiffies
+
POLL_TIMEOUT
);
/* Start sending address & enable interrupt*/
write_reg
(
reg_control
,
read_reg
(
reg_control
)
|
KW_I2C_CTL_XADDR
);
write_reg
(
reg_ier
,
KW_I2C_IRQ_MASK
);
#ifdef POLLED_MODE
DBG
(
"using polled mode...
\n
"
);
/* State machine, to turn into an interrupt handler */
while
(
iface
->
state
!=
state_idle
)
{
u8
isr
=
wait_interrupt
(
iface
);
handle_interrupt
(
iface
,
isr
);
}
#else
/* POLLED_MODE */
DBG
(
"using interrupt mode...
\n
"
);
wait_for_completion
(
&
iface
->
complete
);
#endif
/* POLLED_MODE */
rc
=
iface
->
result
;
if
(
rc
==
0
)
...
...
@@ -540,8 +487,8 @@ create_iface(struct device_node* np)
*
prate
);
}
/* Select standard
sub mode
*/
iface
->
cur_mode
|=
KW_I2C_MODE_STANDARD
SUB
;
/* Select standard
mode by default
*/
iface
->
cur_mode
|=
KW_I2C_MODE_STANDARD
;
/* Write mode */
write_reg
(
reg_mode
,
iface
->
cur_mode
);
...
...
@@ -550,7 +497,6 @@ create_iface(struct device_node* np)
write_reg
(
reg_ier
,
0x00
);
write_reg
(
reg_isr
,
KW_I2C_IRQ_MASK
);
#ifndef POLLED_MODE
/* Request chip interrupt */
rc
=
request_irq
(
iface
->
irq
,
keywest_irq
,
0
,
"keywest i2c"
,
iface
);
if
(
rc
)
{
...
...
@@ -559,7 +505,6 @@ create_iface(struct device_node* np)
kfree
(
iface
);
return
-
ENODEV
;
}
#endif
/* POLLED_MODE */
for
(
i
=
0
;
i
<
nchan
;
i
++
)
{
struct
keywest_chan
*
chan
=
&
iface
->
channels
[
i
];
...
...
@@ -609,19 +554,16 @@ dispose_iface(struct keywest_iface *iface)
/* Make sure we stop all activity */
down
(
&
iface
->
sem
);
#ifndef POLLED_MODE
spin_lock_irq
(
&
iface
->
lock
);
while
(
iface
->
state
!=
state_idle
)
{
spin_unlock_irq
(
&
iface
->
lock
);
schedule
();
set_task_state
(
current
,
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
/
10
);
spin_lock_irq
(
&
iface
->
lock
);
}
#endif
/* POLLED_MODE */
iface
->
state
=
state_dead
;
#ifndef POLLED_MODE
spin_unlock_irq
(
&
iface
->
lock
);
free_irq
(
iface
->
irq
,
iface
);
#endif
/* POLLED_MODE */
up
(
&
iface
->
sem
);
/* Release all channels */
...
...
include/linux/i2c.h
View file @
6fd6bef3
...
...
@@ -594,4 +594,11 @@ union i2c_smbus_data {
#define i2c_is_isa_adapter(adapptr) \
((adapptr)->algo->id == I2C_ALGO_ISA)
/* Tiny delay function used by the i2c bus drivers */
static
inline
void
i2c_delay
(
signed
long
timeout
)
{
set_current_state
(
TASK_INTERRUPTIBLE
);
schedule_timeout
(
timeout
);
}
#endif
/* _LINUX_I2C_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment