Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
88f60f62
Commit
88f60f62
authored
Jan 05, 2009
by
Ben Dooks
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'i2c-next-s3c' into i2c-next
parents
e355204e
e0d1ec97
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
78 additions
and
107 deletions
+78
-107
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-s3c2410.c
+78
-107
No files found.
drivers/i2c/busses/i2c-s3c2410.c
View file @
88f60f62
...
@@ -35,11 +35,9 @@
...
@@ -35,11 +35,9 @@
#include <linux/clk.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/cpufreq.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/io.h>
#include <mach/regs-gpio.h>
#include <asm/plat-s3c/regs-iic.h>
#include <asm/plat-s3c/regs-iic.h>
#include <asm/plat-s3c/iic.h>
#include <asm/plat-s3c/iic.h>
...
@@ -63,6 +61,7 @@ struct s3c24xx_i2c {
...
@@ -63,6 +61,7 @@ struct s3c24xx_i2c {
unsigned
int
msg_ptr
;
unsigned
int
msg_ptr
;
unsigned
int
tx_setup
;
unsigned
int
tx_setup
;
unsigned
int
irq
;
enum
s3c24xx_i2c_state
state
;
enum
s3c24xx_i2c_state
state
;
unsigned
long
clkrate
;
unsigned
long
clkrate
;
...
@@ -70,7 +69,6 @@ struct s3c24xx_i2c {
...
@@ -70,7 +69,6 @@ struct s3c24xx_i2c {
void
__iomem
*
regs
;
void
__iomem
*
regs
;
struct
clk
*
clk
;
struct
clk
*
clk
;
struct
device
*
dev
;
struct
device
*
dev
;
struct
resource
*
irq
;
struct
resource
*
ioarea
;
struct
resource
*
ioarea
;
struct
i2c_adapter
adap
;
struct
i2c_adapter
adap
;
...
@@ -79,16 +77,7 @@ struct s3c24xx_i2c {
...
@@ -79,16 +77,7 @@ struct s3c24xx_i2c {
#endif
#endif
};
};
/* default platform data to use if not supplied in the platform_device
/* default platform data removed, dev should always carry data. */
*/
static
struct
s3c2410_platform_i2c
s3c24xx_i2c_default_platform
=
{
.
flags
=
0
,
.
slave_addr
=
0x10
,
.
bus_freq
=
100
*
1000
,
.
max_freq
=
400
*
1000
,
.
sda_delay
=
S3C2410_IICLC_SDA_DELAY5
|
S3C2410_IICLC_FILTER_ON
,
};
/* s3c24xx_i2c_is2440()
/* s3c24xx_i2c_is2440()
*
*
...
@@ -102,21 +91,6 @@ static inline int s3c24xx_i2c_is2440(struct s3c24xx_i2c *i2c)
...
@@ -102,21 +91,6 @@ static inline int s3c24xx_i2c_is2440(struct s3c24xx_i2c *i2c)
return
!
strcmp
(
pdev
->
name
,
"s3c2440-i2c"
);
return
!
strcmp
(
pdev
->
name
,
"s3c2440-i2c"
);
}
}
/* s3c24xx_i2c_get_platformdata
*
* get the platform data associated with the given device, or return
* the default if there is none
*/
static
inline
struct
s3c2410_platform_i2c
*
s3c24xx_i2c_get_platformdata
(
struct
device
*
dev
)
{
if
(
dev
->
platform_data
!=
NULL
)
return
(
struct
s3c2410_platform_i2c
*
)
dev
->
platform_data
;
return
&
s3c24xx_i2c_default_platform
;
}
/* s3c24xx_i2c_master_complete
/* s3c24xx_i2c_master_complete
*
*
* complete the message and wake up the caller, using the given return code,
* complete the message and wake up the caller, using the given return code,
...
@@ -129,7 +103,7 @@ static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
...
@@ -129,7 +103,7 @@ static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
i2c
->
msg_ptr
=
0
;
i2c
->
msg_ptr
=
0
;
i2c
->
msg
=
NULL
;
i2c
->
msg
=
NULL
;
i2c
->
msg_idx
++
;
i2c
->
msg_idx
++
;
i2c
->
msg_num
=
0
;
i2c
->
msg_num
=
0
;
if
(
ret
)
if
(
ret
)
i2c
->
msg_idx
=
ret
;
i2c
->
msg_idx
=
ret
;
...
@@ -140,19 +114,17 @@ static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
...
@@ -140,19 +114,17 @@ static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
static
inline
void
s3c24xx_i2c_disable_ack
(
struct
s3c24xx_i2c
*
i2c
)
static
inline
void
s3c24xx_i2c_disable_ack
(
struct
s3c24xx_i2c
*
i2c
)
{
{
unsigned
long
tmp
;
unsigned
long
tmp
;
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
tmp
&
~
S3C2410_IICCON_ACKEN
,
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
tmp
&
~
S3C2410_IICCON_ACKEN
,
i2c
->
regs
+
S3C2410_IICCON
);
}
}
static
inline
void
s3c24xx_i2c_enable_ack
(
struct
s3c24xx_i2c
*
i2c
)
static
inline
void
s3c24xx_i2c_enable_ack
(
struct
s3c24xx_i2c
*
i2c
)
{
{
unsigned
long
tmp
;
unsigned
long
tmp
;
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
tmp
|
S3C2410_IICCON_ACKEN
,
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
tmp
|
S3C2410_IICCON_ACKEN
,
i2c
->
regs
+
S3C2410_IICCON
);
}
}
/* irq enable/disable functions */
/* irq enable/disable functions */
...
@@ -160,7 +132,7 @@ static inline void s3c24xx_i2c_enable_ack(struct s3c24xx_i2c *i2c)
...
@@ -160,7 +132,7 @@ static inline void s3c24xx_i2c_enable_ack(struct s3c24xx_i2c *i2c)
static
inline
void
s3c24xx_i2c_disable_irq
(
struct
s3c24xx_i2c
*
i2c
)
static
inline
void
s3c24xx_i2c_disable_irq
(
struct
s3c24xx_i2c
*
i2c
)
{
{
unsigned
long
tmp
;
unsigned
long
tmp
;
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
tmp
&
~
S3C2410_IICCON_IRQEN
,
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
tmp
&
~
S3C2410_IICCON_IRQEN
,
i2c
->
regs
+
S3C2410_IICCON
);
}
}
...
@@ -168,7 +140,7 @@ static inline void s3c24xx_i2c_disable_irq(struct s3c24xx_i2c *i2c)
...
@@ -168,7 +140,7 @@ static inline void s3c24xx_i2c_disable_irq(struct s3c24xx_i2c *i2c)
static
inline
void
s3c24xx_i2c_enable_irq
(
struct
s3c24xx_i2c
*
i2c
)
static
inline
void
s3c24xx_i2c_enable_irq
(
struct
s3c24xx_i2c
*
i2c
)
{
{
unsigned
long
tmp
;
unsigned
long
tmp
;
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
tmp
|
S3C2410_IICCON_IRQEN
,
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
tmp
|
S3C2410_IICCON_IRQEN
,
i2c
->
regs
+
S3C2410_IICCON
);
}
}
...
@@ -176,10 +148,10 @@ static inline void s3c24xx_i2c_enable_irq(struct s3c24xx_i2c *i2c)
...
@@ -176,10 +148,10 @@ static inline void s3c24xx_i2c_enable_irq(struct s3c24xx_i2c *i2c)
/* s3c24xx_i2c_message_start
/* s3c24xx_i2c_message_start
*
*
* put the start of a message onto the bus
* put the start of a message onto the bus
*/
*/
static
void
s3c24xx_i2c_message_start
(
struct
s3c24xx_i2c
*
i2c
,
static
void
s3c24xx_i2c_message_start
(
struct
s3c24xx_i2c
*
i2c
,
struct
i2c_msg
*
msg
)
struct
i2c_msg
*
msg
)
{
{
unsigned
int
addr
=
(
msg
->
addr
&
0x7f
)
<<
1
;
unsigned
int
addr
=
(
msg
->
addr
&
0x7f
)
<<
1
;
...
@@ -198,15 +170,15 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
...
@@ -198,15 +170,15 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
if
(
msg
->
flags
&
I2C_M_REV_DIR_ADDR
)
if
(
msg
->
flags
&
I2C_M_REV_DIR_ADDR
)
addr
^=
1
;
addr
^=
1
;
/
/ todo - check for wether ack wanted or not
/
* todo - check for wether ack wanted or not */
s3c24xx_i2c_enable_ack
(
i2c
);
s3c24xx_i2c_enable_ack
(
i2c
);
iiccon
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
iiccon
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
stat
,
i2c
->
regs
+
S3C2410_IICSTAT
);
writel
(
stat
,
i2c
->
regs
+
S3C2410_IICSTAT
);
dev_dbg
(
i2c
->
dev
,
"START: %08lx to IICSTAT, %02x to DS
\n
"
,
stat
,
addr
);
dev_dbg
(
i2c
->
dev
,
"START: %08lx to IICSTAT, %02x to DS
\n
"
,
stat
,
addr
);
writeb
(
addr
,
i2c
->
regs
+
S3C2410_IICDS
);
writeb
(
addr
,
i2c
->
regs
+
S3C2410_IICDS
);
/* delay here to ensure the data byte has gotten onto the bus
/* delay here to ensure the data byte has gotten onto the bus
* before the transaction is started */
* before the transaction is started */
...
@@ -214,8 +186,8 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
...
@@ -214,8 +186,8 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
dev_dbg
(
i2c
->
dev
,
"iiccon, %08lx
\n
"
,
iiccon
);
dev_dbg
(
i2c
->
dev
,
"iiccon, %08lx
\n
"
,
iiccon
);
writel
(
iiccon
,
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
iiccon
,
i2c
->
regs
+
S3C2410_IICCON
);
stat
|=
S3C2410_IICSTAT_START
;
stat
|=
S3C2410_IICSTAT_START
;
writel
(
stat
,
i2c
->
regs
+
S3C2410_IICSTAT
);
writel
(
stat
,
i2c
->
regs
+
S3C2410_IICSTAT
);
}
}
...
@@ -226,11 +198,11 @@ static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
...
@@ -226,11 +198,11 @@ static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
dev_dbg
(
i2c
->
dev
,
"STOP
\n
"
);
dev_dbg
(
i2c
->
dev
,
"STOP
\n
"
);
/* stop the transfer */
/* stop the transfer */
iicstat
&=
~
S3C2410_IICSTAT_START
;
iicstat
&=
~
S3C2410_IICSTAT_START
;
writel
(
iicstat
,
i2c
->
regs
+
S3C2410_IICSTAT
);
writel
(
iicstat
,
i2c
->
regs
+
S3C2410_IICSTAT
);
i2c
->
state
=
STATE_STOP
;
i2c
->
state
=
STATE_STOP
;
s3c24xx_i2c_master_complete
(
i2c
,
ret
);
s3c24xx_i2c_master_complete
(
i2c
,
ret
);
s3c24xx_i2c_disable_irq
(
i2c
);
s3c24xx_i2c_disable_irq
(
i2c
);
}
}
...
@@ -240,7 +212,7 @@ static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
...
@@ -240,7 +212,7 @@ static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
/* is_lastmsg()
/* is_lastmsg()
*
*
* returns TRUE if the current message is the last in the set
* returns TRUE if the current message is the last in the set
*/
*/
static
inline
int
is_lastmsg
(
struct
s3c24xx_i2c
*
i2c
)
static
inline
int
is_lastmsg
(
struct
s3c24xx_i2c
*
i2c
)
...
@@ -288,14 +260,14 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
...
@@ -288,14 +260,14 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
case
STATE_STOP
:
case
STATE_STOP
:
dev_err
(
i2c
->
dev
,
"%s: called in STATE_STOP
\n
"
,
__func__
);
dev_err
(
i2c
->
dev
,
"%s: called in STATE_STOP
\n
"
,
__func__
);
s3c24xx_i2c_disable_irq
(
i2c
);
s3c24xx_i2c_disable_irq
(
i2c
);
goto
out_ack
;
goto
out_ack
;
case
STATE_START
:
case
STATE_START
:
/* last thing we did was send a start condition on the
/* last thing we did was send a start condition on the
* bus, or started a new i2c message
* bus, or started a new i2c message
*/
*/
if
(
iicstat
&
S3C2410_IICSTAT_LASTBIT
&&
if
(
iicstat
&
S3C2410_IICSTAT_LASTBIT
&&
!
(
i2c
->
msg
->
flags
&
I2C_M_IGNORE_NAK
))
{
!
(
i2c
->
msg
->
flags
&
I2C_M_IGNORE_NAK
))
{
/* ack was not received... */
/* ack was not received... */
...
@@ -321,7 +293,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
...
@@ -321,7 +293,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
if
(
i2c
->
state
==
STATE_READ
)
if
(
i2c
->
state
==
STATE_READ
)
goto
prepare_read
;
goto
prepare_read
;
/* fall through to the write state, as we will need to
/* fall through to the write state, as we will need to
* send a byte as well */
* send a byte as well */
case
STATE_WRITE
:
case
STATE_WRITE
:
...
@@ -338,7 +310,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
...
@@ -338,7 +310,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
}
}
}
}
retry_write:
retry_write:
if
(
!
is_msgend
(
i2c
))
{
if
(
!
is_msgend
(
i2c
))
{
byte
=
i2c
->
msg
->
buf
[
i2c
->
msg_ptr
++
];
byte
=
i2c
->
msg
->
buf
[
i2c
->
msg_ptr
++
];
...
@@ -358,9 +330,9 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
...
@@ -358,9 +330,9 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
dev_dbg
(
i2c
->
dev
,
"WRITE: Next Message
\n
"
);
dev_dbg
(
i2c
->
dev
,
"WRITE: Next Message
\n
"
);
i2c
->
msg_ptr
=
0
;
i2c
->
msg_ptr
=
0
;
i2c
->
msg_idx
++
;
i2c
->
msg_idx
++
;
i2c
->
msg
++
;
i2c
->
msg
++
;
/* check to see if we need to do another message */
/* check to see if we need to do another message */
if
(
i2c
->
msg
->
flags
&
I2C_M_NOSTART
)
{
if
(
i2c
->
msg
->
flags
&
I2C_M_NOSTART
)
{
...
@@ -374,7 +346,6 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
...
@@ -374,7 +346,6 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
goto
retry_write
;
goto
retry_write
;
}
else
{
}
else
{
/* send the new start */
/* send the new start */
s3c24xx_i2c_message_start
(
i2c
,
i2c
->
msg
);
s3c24xx_i2c_message_start
(
i2c
,
i2c
->
msg
);
i2c
->
state
=
STATE_START
;
i2c
->
state
=
STATE_START
;
...
@@ -388,7 +359,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
...
@@ -388,7 +359,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
break
;
break
;
case
STATE_READ
:
case
STATE_READ
:
/* we have a byte of data in the data register, do
/* we have a byte of data in the data register, do
* something with it, and then work out wether we are
* something with it, and then work out wether we are
* going to do any more read/write
* going to do any more read/write
*/
*/
...
@@ -396,13 +367,13 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
...
@@ -396,13 +367,13 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
byte
=
readb
(
i2c
->
regs
+
S3C2410_IICDS
);
byte
=
readb
(
i2c
->
regs
+
S3C2410_IICDS
);
i2c
->
msg
->
buf
[
i2c
->
msg_ptr
++
]
=
byte
;
i2c
->
msg
->
buf
[
i2c
->
msg_ptr
++
]
=
byte
;
prepare_read:
prepare_read:
if
(
is_msglast
(
i2c
))
{
if
(
is_msglast
(
i2c
))
{
/* last byte of buffer */
/* last byte of buffer */
if
(
is_lastmsg
(
i2c
))
if
(
is_lastmsg
(
i2c
))
s3c24xx_i2c_disable_ack
(
i2c
);
s3c24xx_i2c_disable_ack
(
i2c
);
}
else
if
(
is_msgend
(
i2c
))
{
}
else
if
(
is_msgend
(
i2c
))
{
/* ok, we've read the entire buffer, see if there
/* ok, we've read the entire buffer, see if there
* is anything else we need to do */
* is anything else we need to do */
...
@@ -428,7 +399,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
...
@@ -428,7 +399,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
/* acknowlegde the IRQ and get back on with the work */
/* acknowlegde the IRQ and get back on with the work */
out_ack:
out_ack:
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
tmp
&=
~
S3C2410_IICCON_IRQPEND
;
tmp
&=
~
S3C2410_IICCON_IRQPEND
;
writel
(
tmp
,
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
tmp
,
i2c
->
regs
+
S3C2410_IICCON
);
out:
out:
...
@@ -449,19 +420,19 @@ static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
...
@@ -449,19 +420,19 @@ static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
status
=
readl
(
i2c
->
regs
+
S3C2410_IICSTAT
);
status
=
readl
(
i2c
->
regs
+
S3C2410_IICSTAT
);
if
(
status
&
S3C2410_IICSTAT_ARBITR
)
{
if
(
status
&
S3C2410_IICSTAT_ARBITR
)
{
/
/ deal with arbitration loss
/
* deal with arbitration loss */
dev_err
(
i2c
->
dev
,
"deal with arbitration loss
\n
"
);
dev_err
(
i2c
->
dev
,
"deal with arbitration loss
\n
"
);
}
}
if
(
i2c
->
state
==
STATE_IDLE
)
{
if
(
i2c
->
state
==
STATE_IDLE
)
{
dev_dbg
(
i2c
->
dev
,
"IRQ: error i2c->state == IDLE
\n
"
);
dev_dbg
(
i2c
->
dev
,
"IRQ: error i2c->state == IDLE
\n
"
);
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
tmp
=
readl
(
i2c
->
regs
+
S3C2410_IICCON
);
tmp
&=
~
S3C2410_IICCON_IRQPEND
;
tmp
&=
~
S3C2410_IICCON_IRQPEND
;
writel
(
tmp
,
i2c
->
regs
+
S3C2410_IICCON
);
writel
(
tmp
,
i2c
->
regs
+
S3C2410_IICCON
);
goto
out
;
goto
out
;
}
}
/* pretty much this leaves us with the fact that we've
/* pretty much this leaves us with the fact that we've
* transmitted or received whatever byte we last sent */
* transmitted or received whatever byte we last sent */
...
@@ -484,16 +455,13 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
...
@@ -484,16 +455,13 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
while
(
timeout
--
>
0
)
{
while
(
timeout
--
>
0
)
{
iicstat
=
readl
(
i2c
->
regs
+
S3C2410_IICSTAT
);
iicstat
=
readl
(
i2c
->
regs
+
S3C2410_IICSTAT
);
if
(
!
(
iicstat
&
S3C2410_IICSTAT_BUSBUSY
))
if
(
!
(
iicstat
&
S3C2410_IICSTAT_BUSBUSY
))
return
0
;
return
0
;
msleep
(
1
);
msleep
(
1
);
}
}
dev_dbg
(
i2c
->
dev
,
"timeout: GPEDAT is %08x
\n
"
,
__raw_readl
(
S3C2410_GPEDAT
));
return
-
ETIMEDOUT
;
return
-
ETIMEDOUT
;
}
}
...
@@ -502,7 +470,8 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
...
@@ -502,7 +470,8 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
* this starts an i2c transfer
* this starts an i2c transfer
*/
*/
static
int
s3c24xx_i2c_doxfer
(
struct
s3c24xx_i2c
*
i2c
,
struct
i2c_msg
*
msgs
,
int
num
)
static
int
s3c24xx_i2c_doxfer
(
struct
s3c24xx_i2c
*
i2c
,
struct
i2c_msg
*
msgs
,
int
num
)
{
{
unsigned
long
timeout
;
unsigned
long
timeout
;
int
ret
;
int
ret
;
...
@@ -528,12 +497,12 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int
...
@@ -528,12 +497,12 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int
s3c24xx_i2c_enable_irq
(
i2c
);
s3c24xx_i2c_enable_irq
(
i2c
);
s3c24xx_i2c_message_start
(
i2c
,
msgs
);
s3c24xx_i2c_message_start
(
i2c
,
msgs
);
spin_unlock_irq
(
&
i2c
->
lock
);
spin_unlock_irq
(
&
i2c
->
lock
);
timeout
=
wait_event_timeout
(
i2c
->
wait
,
i2c
->
msg_num
==
0
,
HZ
*
5
);
timeout
=
wait_event_timeout
(
i2c
->
wait
,
i2c
->
msg_num
==
0
,
HZ
*
5
);
ret
=
i2c
->
msg_idx
;
ret
=
i2c
->
msg_idx
;
/* having these next two as dev_err() makes life very
/* having these next two as dev_err() makes life very
* noisy when doing an i2cdetect */
* noisy when doing an i2cdetect */
if
(
timeout
==
0
)
if
(
timeout
==
0
)
...
@@ -590,19 +559,6 @@ static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
...
@@ -590,19 +559,6 @@ static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
.
functionality
=
s3c24xx_i2c_func
,
.
functionality
=
s3c24xx_i2c_func
,
};
};
static
struct
s3c24xx_i2c
s3c24xx_i2c
=
{
.
lock
=
__SPIN_LOCK_UNLOCKED
(
s3c24xx_i2c
.
lock
),
.
wait
=
__WAIT_QUEUE_HEAD_INITIALIZER
(
s3c24xx_i2c
.
wait
),
.
tx_setup
=
50
,
.
adap
=
{
.
name
=
"s3c2410-i2c"
,
.
owner
=
THIS_MODULE
,
.
algo
=
&
s3c24xx_i2c_algorithm
,
.
retries
=
2
,
.
class
=
I2C_CLASS_HWMON
|
I2C_CLASS_SPD
,
},
};
/* s3c24xx_i2c_calcdivisor
/* s3c24xx_i2c_calcdivisor
*
*
* return the divisor settings for a given frequency
* return the divisor settings for a given frequency
...
@@ -642,7 +598,7 @@ static inline int freq_acceptable(unsigned int freq, unsigned int wanted)
...
@@ -642,7 +598,7 @@ static inline int freq_acceptable(unsigned int freq, unsigned int wanted)
{
{
int
diff
=
freq
-
wanted
;
int
diff
=
freq
-
wanted
;
return
(
diff
>=
-
2
&&
diff
<=
2
)
;
return
diff
>=
-
2
&&
diff
<=
2
;
}
}
/* s3c24xx_i2c_clockrate
/* s3c24xx_i2c_clockrate
...
@@ -654,7 +610,7 @@ static inline int freq_acceptable(unsigned int freq, unsigned int wanted)
...
@@ -654,7 +610,7 @@ static inline int freq_acceptable(unsigned int freq, unsigned int wanted)
static
int
s3c24xx_i2c_clockrate
(
struct
s3c24xx_i2c
*
i2c
,
unsigned
int
*
got
)
static
int
s3c24xx_i2c_clockrate
(
struct
s3c24xx_i2c
*
i2c
,
unsigned
int
*
got
)
{
{
struct
s3c2410_platform_i2c
*
pdata
;
struct
s3c2410_platform_i2c
*
pdata
=
i2c
->
dev
->
platform_data
;
unsigned
long
clkin
=
clk_get_rate
(
i2c
->
clk
);
unsigned
long
clkin
=
clk_get_rate
(
i2c
->
clk
);
unsigned
int
divs
,
div1
;
unsigned
int
divs
,
div1
;
u32
iiccon
;
u32
iiccon
;
...
@@ -662,10 +618,8 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
...
@@ -662,10 +618,8 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
int
start
,
end
;
int
start
,
end
;
i2c
->
clkrate
=
clkin
;
i2c
->
clkrate
=
clkin
;
pdata
=
s3c24xx_i2c_get_platformdata
(
i2c
->
adap
.
dev
.
parent
);
clkin
/=
1000
;
/* clkin now in KHz */
clkin
/=
1000
;
/* clkin now in KHz */
dev_dbg
(
i2c
->
dev
,
"pdata %p, freq %lu %lu..%lu
\n
"
,
dev_dbg
(
i2c
->
dev
,
"pdata %p, freq %lu %lu..%lu
\n
"
,
pdata
,
pdata
->
bus_freq
,
pdata
->
min_freq
,
pdata
->
max_freq
);
pdata
,
pdata
->
bus_freq
,
pdata
->
min_freq
,
pdata
->
max_freq
);
...
@@ -773,7 +727,7 @@ static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
...
@@ -773,7 +727,7 @@ static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
/* s3c24xx_i2c_init
/* s3c24xx_i2c_init
*
*
* initialise the controller, set the IO lines and frequency
* initialise the controller, set the IO lines and frequency
*/
*/
static
int
s3c24xx_i2c_init
(
struct
s3c24xx_i2c
*
i2c
)
static
int
s3c24xx_i2c_init
(
struct
s3c24xx_i2c
*
i2c
)
...
@@ -784,15 +738,15 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
...
@@ -784,15 +738,15 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
/* get the plafrom data */
/* get the plafrom data */
pdata
=
s3c24xx_i2c_get_platformdata
(
i2c
->
adap
.
dev
.
parent
)
;
pdata
=
i2c
->
dev
->
platform_data
;
/* inititalise the gpio */
/* inititalise the gpio */
s3c2410_gpio_cfgpin
(
S3C2410_GPE15
,
S3C2410_GPE15_IICSDA
);
if
(
pdata
->
cfg_gpio
)
s3c2410_gpio_cfgpin
(
S3C2410_GPE14
,
S3C2410_GPE14_IICSCL
);
pdata
->
cfg_gpio
(
to_platform_device
(
i2c
->
dev
)
);
/* write slave address */
/* write slave address */
writeb
(
pdata
->
slave_addr
,
i2c
->
regs
+
S3C2410_IICADD
);
writeb
(
pdata
->
slave_addr
,
i2c
->
regs
+
S3C2410_IICADD
);
dev_info
(
i2c
->
dev
,
"slave address 0x%02x
\n
"
,
pdata
->
slave_addr
);
dev_info
(
i2c
->
dev
,
"slave address 0x%02x
\n
"
,
pdata
->
slave_addr
);
...
@@ -830,12 +784,32 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
...
@@ -830,12 +784,32 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
static
int
s3c24xx_i2c_probe
(
struct
platform_device
*
pdev
)
static
int
s3c24xx_i2c_probe
(
struct
platform_device
*
pdev
)
{
{
struct
s3c24xx_i2c
*
i2c
=
&
s3c24xx_i2c
;
struct
s3c24xx_i2c
*
i2c
;
struct
s3c2410_platform_i2c
*
pdata
;
struct
s3c2410_platform_i2c
*
pdata
;
struct
resource
*
res
;
struct
resource
*
res
;
int
ret
;
int
ret
;
pdata
=
s3c24xx_i2c_get_platformdata
(
&
pdev
->
dev
);
pdata
=
pdev
->
dev
.
platform_data
;
if
(
!
pdata
)
{
dev_err
(
&
pdev
->
dev
,
"no platform data
\n
"
);
return
-
EINVAL
;
}
i2c
=
kzalloc
(
sizeof
(
struct
s3c24xx_i2c
),
GFP_KERNEL
);
if
(
!
i2c
)
{
dev_err
(
&
pdev
->
dev
,
"no memory for state
\n
"
);
return
-
ENOMEM
;
}
strlcpy
(
i2c
->
adap
.
name
,
"s3c2410-i2c"
,
sizeof
(
i2c
->
adap
.
name
));
i2c
->
adap
.
owner
=
THIS_MODULE
;
i2c
->
adap
.
algo
=
&
s3c24xx_i2c_algorithm
;
i2c
->
adap
.
retries
=
2
;
i2c
->
adap
.
class
=
I2C_CLASS_HWMON
|
I2C_CLASS_SPD
;
i2c
->
tx_setup
=
50
;
spin_lock_init
(
&
i2c
->
lock
);
init_waitqueue_head
(
&
i2c
->
wait
);
/* find the clock and enable it */
/* find the clock and enable it */
...
@@ -877,7 +851,8 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
...
@@ -877,7 +851,8 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
goto
err_ioarea
;
goto
err_ioarea
;
}
}
dev_dbg
(
&
pdev
->
dev
,
"registers %p (%p, %p)
\n
"
,
i2c
->
regs
,
i2c
->
ioarea
,
res
);
dev_dbg
(
&
pdev
->
dev
,
"registers %p (%p, %p)
\n
"
,
i2c
->
regs
,
i2c
->
ioarea
,
res
);
/* setup info block for the i2c core */
/* setup info block for the i2c core */
...
@@ -891,29 +866,23 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
...
@@ -891,29 +866,23 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
goto
err_iomap
;
goto
err_iomap
;
/* find the IRQ for this unit (note, this relies on the init call to
/* find the IRQ for this unit (note, this relies on the init call to
* ensure no current IRQs pending
* ensure no current IRQs pending
*/
*/
res
=
platform_get_resource
(
pdev
,
IORESOURCE_IRQ
,
0
);
i2c
->
irq
=
ret
=
platform_get_irq
(
pdev
,
0
);
if
(
re
s
==
NULL
)
{
if
(
re
t
<=
0
)
{
dev_err
(
&
pdev
->
dev
,
"cannot find IRQ
\n
"
);
dev_err
(
&
pdev
->
dev
,
"cannot find IRQ
\n
"
);
ret
=
-
ENOENT
;
goto
err_iomap
;
goto
err_iomap
;
}
}
ret
=
request_irq
(
res
->
start
,
s3c24xx_i2c_irq
,
IRQF_DISABLED
,
ret
=
request_irq
(
i2c
->
irq
,
s3c24xx_i2c_irq
,
IRQF_DISABLED
,
pdev
->
name
,
i2c
);
dev_name
(
&
pdev
->
dev
)
,
i2c
);
if
(
ret
!=
0
)
{
if
(
ret
!=
0
)
{
dev_err
(
&
pdev
->
dev
,
"cannot claim IRQ
\n
"
);
dev_err
(
&
pdev
->
dev
,
"cannot claim IRQ
%d
\n
"
,
i2c
->
irq
);
goto
err_iomap
;
goto
err_iomap
;
}
}
i2c
->
irq
=
res
;
dev_dbg
(
&
pdev
->
dev
,
"irq resource %p (%lu)
\n
"
,
res
,
(
unsigned
long
)
res
->
start
);
ret
=
s3c24xx_i2c_register_cpufreq
(
i2c
);
ret
=
s3c24xx_i2c_register_cpufreq
(
i2c
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"failed to register cpufreq notifier
\n
"
);
dev_err
(
&
pdev
->
dev
,
"failed to register cpufreq notifier
\n
"
);
...
@@ -943,7 +912,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
...
@@ -943,7 +912,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
s3c24xx_i2c_deregister_cpufreq
(
i2c
);
s3c24xx_i2c_deregister_cpufreq
(
i2c
);
err_irq:
err_irq:
free_irq
(
i2c
->
irq
->
start
,
i2c
);
free_irq
(
i2c
->
irq
,
i2c
);
err_iomap:
err_iomap:
iounmap
(
i2c
->
regs
);
iounmap
(
i2c
->
regs
);
...
@@ -957,6 +926,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
...
@@ -957,6 +926,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
clk_put
(
i2c
->
clk
);
clk_put
(
i2c
->
clk
);
err_noclk:
err_noclk:
kfree
(
i2c
);
return
ret
;
return
ret
;
}
}
...
@@ -972,7 +942,7 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
...
@@ -972,7 +942,7 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
s3c24xx_i2c_deregister_cpufreq
(
i2c
);
s3c24xx_i2c_deregister_cpufreq
(
i2c
);
i2c_del_adapter
(
&
i2c
->
adap
);
i2c_del_adapter
(
&
i2c
->
adap
);
free_irq
(
i2c
->
irq
->
start
,
i2c
);
free_irq
(
i2c
->
irq
,
i2c
);
clk_disable
(
i2c
->
clk
);
clk_disable
(
i2c
->
clk
);
clk_put
(
i2c
->
clk
);
clk_put
(
i2c
->
clk
);
...
@@ -981,6 +951,7 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
...
@@ -981,6 +951,7 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
release_resource
(
i2c
->
ioarea
);
release_resource
(
i2c
->
ioarea
);
kfree
(
i2c
->
ioarea
);
kfree
(
i2c
->
ioarea
);
kfree
(
i2c
);
return
0
;
return
0
;
}
}
...
...
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