Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
reform-boundary-uboot
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jack Humbert
reform-boundary-uboot
Commits
a6be70f7
Commit
a6be70f7
authored
10 years ago
by
Scott Jiang
Committed by
Heiko Schocher
10 years ago
Browse files
Options
Downloads
Patches
Plain Diff
adi_i2c: convert to use general io accessors.
Signed-off-by:
Scott Jiang
<
scott.jiang.linux@gmail.com
>
parent
fea9b69a
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
drivers/i2c/adi_i2c.c
+77
-68
77 additions, 68 deletions
drivers/i2c/adi_i2c.c
with
77 additions
and
68 deletions
drivers/i2c/adi_i2c.c
+
77
−
68
View file @
a6be70f7
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
#include
<asm/clock.h>
#include
<asm/clock.h>
#include
<asm/twi.h>
#include
<asm/twi.h>
#include
<asm/io.h>
/* Every register is 32bit aligned, but only 16bits in size */
/* Every register is 32bit aligned, but only 16bits in size */
#define ureg(name) u16 name; u16 __pad_##name;
#define ureg(name) u16 name; u16 __pad_##name;
...
@@ -39,7 +40,7 @@ struct twi_regs {
...
@@ -39,7 +40,7 @@ struct twi_regs {
#ifdef TWI_CLKDIV
#ifdef TWI_CLKDIV
#define TWI0_CLKDIV TWI_CLKDIV
#define TWI0_CLKDIV TWI_CLKDIV
#endif
#endif
static
volatile
struct
twi_regs
*
twi
=
(
void
*
)
TWI0_CLKDIV
;
static
struct
twi_regs
*
twi
=
(
void
*
)
TWI0_CLKDIV
;
#ifdef DEBUG
#ifdef DEBUG
# define dmemset(s, c, n) memset(s, c, n)
# define dmemset(s, c, n) memset(s, c, n)
...
@@ -93,53 +94,54 @@ struct i2c_msg {
...
@@ -93,53 +94,54 @@ struct i2c_msg {
*/
*/
static
int
wait_for_completion
(
struct
i2c_msg
*
msg
)
static
int
wait_for_completion
(
struct
i2c_msg
*
msg
)
{
{
u
int16_t
int_stat
;
u
16
int_stat
,
ctl
;
ulong
timebase
=
get_timer
(
0
);
ulong
timebase
=
get_timer
(
0
);
do
{
do
{
int_stat
=
twi
->
int_stat
;
int_stat
=
readw
(
&
twi
->
int_stat
)
;
if
(
int_stat
&
XMTSERV
)
{
if
(
int_stat
&
XMTSERV
)
{
debugi
(
"processing XMTSERV"
);
debugi
(
"processing XMTSERV"
);
twi
->
int_stat
=
XMTSERV
;
writew
(
XMTSERV
,
&
twi
->
int_stat
);
SSYNC
();
if
(
msg
->
alen
)
{
if
(
msg
->
alen
)
{
twi
->
xmt_data8
=
*
(
msg
->
abuf
++
);
writew
(
*
(
msg
->
abuf
++
),
&
twi
->
xmt_data8
);
--
msg
->
alen
;
--
msg
->
alen
;
}
else
if
(
!
(
msg
->
flags
&
I2C_M_COMBO
)
&&
msg
->
len
)
{
}
else
if
(
!
(
msg
->
flags
&
I2C_M_COMBO
)
&&
msg
->
len
)
{
twi
->
xmt_data8
=
*
(
msg
->
buf
++
);
writew
(
*
(
msg
->
buf
++
),
&
twi
->
xmt_data8
);
--
msg
->
len
;
--
msg
->
len
;
}
else
{
}
else
{
twi
->
master_ctl
|=
(
msg
->
flags
&
I2C_M_COMBO
)
?
RSTART
|
MDIR
:
STOP
;
ctl
=
readw
(
&
twi
->
master_ctl
);
SSYNC
();
if
(
msg
->
flags
&
I2C_M_COMBO
)
writew
(
ctl
|
RSTART
|
MDIR
,
&
twi
->
master_ctl
);
else
writew
(
ctl
|
STOP
,
&
twi
->
master_ctl
);
}
}
}
}
if
(
int_stat
&
RCVSERV
)
{
if
(
int_stat
&
RCVSERV
)
{
debugi
(
"processing RCVSERV"
);
debugi
(
"processing RCVSERV"
);
twi
->
int_stat
=
RCVSERV
;
writew
(
RCVSERV
,
&
twi
->
int_stat
);
SSYNC
();
if
(
msg
->
len
)
{
if
(
msg
->
len
)
{
*
(
msg
->
buf
++
)
=
twi
->
rcv_data8
;
*
(
msg
->
buf
++
)
=
readw
(
&
twi
->
rcv_data8
)
;
--
msg
->
len
;
--
msg
->
len
;
}
else
if
(
msg
->
flags
&
I2C_M_STOP
)
{
}
else
if
(
msg
->
flags
&
I2C_M_STOP
)
{
twi
->
master_ctl
|=
STOP
;
ctl
=
readw
(
&
twi
->
master_ctl
)
;
SSYNC
(
);
writew
(
ctl
|
STOP
,
&
twi
->
master_ctl
);
}
}
}
}
if
(
int_stat
&
MERR
)
{
if
(
int_stat
&
MERR
)
{
debugi
(
"processing MERR"
);
debugi
(
"processing MERR"
);
twi
->
int_stat
=
MERR
;
writew
(
MERR
,
&
twi
->
int_stat
);
SSYNC
();
return
msg
->
len
;
return
msg
->
len
;
}
}
if
(
int_stat
&
MCOMP
)
{
if
(
int_stat
&
MCOMP
)
{
debugi
(
"processing MCOMP"
);
debugi
(
"processing MCOMP"
);
twi
->
int_stat
=
MCOMP
;
writew
(
MCOMP
,
&
twi
->
int_stat
);
SSYNC
();
if
(
msg
->
flags
&
I2C_M_COMBO
&&
msg
->
len
)
{
if
(
msg
->
flags
&
I2C_M_COMBO
&&
msg
->
len
)
{
twi
->
master_ctl
=
(
twi
->
master_ctl
&
~
RSTART
)
|
ctl
=
readw
(
&
twi
->
master_ctl
);
ctl
=
(
ctl
&
~
RSTART
)
|
(
min
(
msg
->
len
,
0xff
)
<<
6
)
|
MEN
|
MDIR
;
(
min
(
msg
->
len
,
0xff
)
<<
6
)
|
MEN
|
MDIR
;
SSYNC
(
);
writew
(
ctl
,
&
twi
->
master_ctl
);
}
else
}
else
break
;
break
;
}
}
...
@@ -160,8 +162,11 @@ static int wait_for_completion(struct i2c_msg *msg)
...
@@ -160,8 +162,11 @@ static int wait_for_completion(struct i2c_msg *msg)
* Here we just get the i2c stuff all prepped and ready, and then tail off
* Here we just get the i2c stuff all prepped and ready, and then tail off
* into wait_for_completion() for all the bits to go.
* into wait_for_completion() for all the bits to go.
*/
*/
static
int
i2c_transfer
(
uchar
chip
,
uint
addr
,
int
alen
,
uchar
*
buffer
,
int
len
,
u8
flags
)
static
int
i2c_transfer
(
uchar
chip
,
uint
addr
,
int
alen
,
uchar
*
buffer
,
int
len
,
u8
flags
)
{
{
int
ret
;
u16
ctl
;
uchar
addr_buffer
[]
=
{
uchar
addr_buffer
[]
=
{
(
addr
>>
0
),
(
addr
>>
0
),
(
addr
>>
8
),
(
addr
>>
8
),
...
@@ -174,62 +179,59 @@ static int i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer, int len,
...
@@ -174,62 +179,59 @@ static int i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer, int len,
.
abuf
=
addr_buffer
,
.
abuf
=
addr_buffer
,
.
alen
=
alen
,
.
alen
=
alen
,
};
};
int
ret
;
dmemset
(
buffer
,
0xff
,
len
);
dmemset
(
buffer
,
0xff
,
len
);
debugi
(
"chip=0x%x addr=0x%02x alen=%i buf[0]=0x%02x len=%i flags=0x%02x[%s] "
,
debugi
(
"chip=0x%x addr=0x%02x alen=%i buf[0]=0x%02x len=%i "
,
chip
,
addr
,
alen
,
buffer
[
0
],
len
,
flags
,
(
flags
&
I2C_M_READ
?
"rd"
:
"wr"
));
chip
,
addr
,
alen
,
buffer
[
0
],
len
);
debugi
(
"flags=0x%02x[%s] "
,
flags
,
(
flags
&
I2C_M_READ
?
"rd"
:
"wr"
));
/* wait for things to settle */
/* wait for things to settle */
while
(
twi
->
master_stat
&
BUSBUSY
)
while
(
readw
(
&
twi
->
master_stat
)
&
BUSBUSY
)
if
(
ctrlc
())
if
(
ctrlc
())
return
1
;
return
1
;
/* Set Transmit device address */
/* Set Transmit device address */
twi
->
master_addr
=
chip
;
writew
(
chip
,
&
twi
->
master_addr
)
;
/* Clear the FIFO before starting things */
/* Clear the FIFO before starting things */
twi
->
fifo_ctl
=
XMTFLUSH
|
RCVFLUSH
;
writew
(
XMTFLUSH
|
RCVFLUSH
,
&
twi
->
fifo_ctl
);
SSYNC
();
writew
(
0
,
&
twi
->
fifo_ctl
);
twi
->
fifo_ctl
=
0
;
SSYNC
();
/* prime the pump */
/* prime the pump */
if
(
msg
.
alen
)
{
if
(
msg
.
alen
)
{
len
=
(
msg
.
flags
&
I2C_M_COMBO
)
?
msg
.
alen
:
msg
.
alen
+
len
;
len
=
(
msg
.
flags
&
I2C_M_COMBO
)
?
msg
.
alen
:
msg
.
alen
+
len
;
debugi
(
"first byte=0x%02x"
,
*
msg
.
abuf
);
debugi
(
"first byte=0x%02x"
,
*
msg
.
abuf
);
twi
->
xmt_data8
=
*
(
msg
.
abuf
++
);
writew
(
*
(
msg
.
abuf
++
),
&
twi
->
xmt_data8
);
--
msg
.
alen
;
--
msg
.
alen
;
}
else
if
(
!
(
msg
.
flags
&
I2C_M_READ
)
&&
msg
.
len
)
{
}
else
if
(
!
(
msg
.
flags
&
I2C_M_READ
)
&&
msg
.
len
)
{
debugi
(
"first byte=0x%02x"
,
*
msg
.
buf
);
debugi
(
"first byte=0x%02x"
,
*
msg
.
buf
);
twi
->
xmt_data8
=
*
(
msg
.
buf
++
);
writew
(
*
(
msg
.
buf
++
),
&
twi
->
xmt_data8
);
--
msg
.
len
;
--
msg
.
len
;
}
}
/* clear int stat */
/* clear int stat */
twi
->
master_stat
=
-
1
;
writew
(
-
1
,
&
twi
->
master_stat
);
twi
->
int_stat
=
-
1
;
writew
(
-
1
,
&
twi
->
int_stat
);
twi
->
int_mask
=
0
;
writew
(
0
,
&
twi
->
int_mask
);
SSYNC
();
/* Master enable */
/* Master enable */
twi
->
master_ctl
=
ctl
=
readw
(
&
twi
->
master_ctl
);
(
twi
->
master_ctl
&
FAST
)
|
ctl
=
(
ctl
&
FAST
)
|
(
min
(
len
,
0xff
)
<<
6
)
|
MEN
|
(
min
(
len
,
0xff
)
<<
6
)
|
MEN
|
((
msg
.
flags
&
I2C_M_READ
)
?
MDIR
:
0
);
((
msg
.
flags
&
I2C_M_READ
)
?
MDIR
:
0
);
writew
(
ctl
,
&
twi
->
master_ctl
);
SSYNC
();
debugi
(
"CTL=0x%04x"
,
twi
->
master_ctl
);
/* process the rest */
/* process the rest */
ret
=
wait_for_completion
(
&
msg
);
ret
=
wait_for_completion
(
&
msg
);
debugi
(
"ret=%d"
,
ret
);
debugi
(
"ret=%d"
,
ret
);
if
(
ret
)
{
if
(
ret
)
{
twi
->
master_ctl
&=
~
MEN
;
ctl
=
readw
(
&
twi
->
master_ctl
)
&
~
MEN
;
twi
->
control
&=
~
TWI_ENA
;
writew
(
ctl
,
&
twi
->
master_ctl
);
SSYNC
();
ctl
=
readw
(
&
twi
->
control
)
&
~
TWI_ENA
;
twi
->
control
|=
TWI_ENA
;
writew
(
ctl
,
&
twi
->
control
);
SSYNC
();
ctl
=
readw
(
&
twi
->
control
)
|
TWI_ENA
;
writew
(
ctl
,
&
twi
->
control
);
}
}
return
ret
;
return
ret
;
...
@@ -246,10 +248,11 @@ int i2c_set_bus_speed(unsigned int speed)
...
@@ -246,10 +248,11 @@ int i2c_set_bus_speed(unsigned int speed)
/* Set TWI interface clock */
/* Set TWI interface clock */
if
(
clkdiv
<
I2C_DUTY_MAX
||
clkdiv
>
I2C_DUTY_MIN
)
if
(
clkdiv
<
I2C_DUTY_MAX
||
clkdiv
>
I2C_DUTY_MIN
)
return
-
1
;
return
-
1
;
twi
->
clkdiv
=
(
clkdiv
<<
8
)
|
(
clkdiv
&
0xff
);
clkdiv
=
(
clkdiv
<<
8
)
|
(
clkdiv
&
0xff
);
writew
(
clkdiv
,
&
twi
->
clkdiv
);
/* Don't turn it on */
/* Don't turn it on */
twi
->
master_ctl
=
(
speed
>
100000
?
FAST
:
0
);
writew
(
speed
>
100000
?
FAST
:
0
,
&
twi
->
master_ctl
);
return
0
;
return
0
;
}
}
...
@@ -260,8 +263,9 @@ int i2c_set_bus_speed(unsigned int speed)
...
@@ -260,8 +263,9 @@ int i2c_set_bus_speed(unsigned int speed)
*/
*/
unsigned
int
i2c_get_bus_speed
(
void
)
unsigned
int
i2c_get_bus_speed
(
void
)
{
{
u16
clkdiv
=
readw
(
&
twi
->
clkdiv
)
&
0xff
;
/* 10 MHz / (2 * CLKDIV) -> 5 MHz / CLKDIV */
/* 10 MHz / (2 * CLKDIV) -> 5 MHz / CLKDIV */
return
5000000
/
(
twi
->
clkdiv
&
0xff
)
;
return
5000000
/
clkdiv
;
}
}
/**
/**
...
@@ -277,24 +281,19 @@ void i2c_init(int speed, int slaveaddr)
...
@@ -277,24 +281,19 @@ void i2c_init(int speed, int slaveaddr)
uint8_t
prescale
=
((
get_i2c_clk
()
/
1000
/
1000
+
5
)
/
10
)
&
0x7F
;
uint8_t
prescale
=
((
get_i2c_clk
()
/
1000
/
1000
+
5
)
/
10
)
&
0x7F
;
/* Set TWI internal clock as 10MHz */
/* Set TWI internal clock as 10MHz */
twi
->
control
=
prescale
;
writew
(
prescale
,
&
twi
->
control
)
;
/* Set TWI interface clock as specified */
/* Set TWI interface clock as specified */
i2c_set_bus_speed
(
speed
);
i2c_set_bus_speed
(
speed
);
/* Enable it */
/* Enable it */
twi
->
control
=
TWI_ENA
|
prescale
;
writew
(
TWI_ENA
|
prescale
,
&
twi
->
control
);
SSYNC
();
debugi
(
"CONTROL:0x%04x CLKDIV:0x%04x"
,
twi
->
control
,
twi
->
clkdiv
);
debugi
(
"CONTROL:0x%04x CLKDIV:0x%04x"
,
readw
(
&
twi
->
control
),
readw
(
&
twi
->
clkdiv
));
#if CONFIG_SYS_I2C_SLAVE
#if CONFIG_SYS_I2C_SLAVE
# error I2C slave support not tested/supported
# error I2C slave support not tested/supported
/* If they want us as a slave, do it */
if
(
slaveaddr
)
{
twi
->
slave_addr
=
slaveaddr
;
twi
->
slave_ctl
=
SEN
;
}
#endif
#endif
}
}
...
@@ -320,7 +319,8 @@ int i2c_probe(uchar chip)
...
@@ -320,7 +319,8 @@ int i2c_probe(uchar chip)
*/
*/
int
i2c_read
(
uchar
chip
,
uint
addr
,
int
alen
,
uchar
*
buffer
,
int
len
)
int
i2c_read
(
uchar
chip
,
uint
addr
,
int
alen
,
uchar
*
buffer
,
int
len
)
{
{
return
i2c_transfer
(
chip
,
addr
,
alen
,
buffer
,
len
,
(
alen
?
I2C_M_COMBO
:
I2C_M_READ
));
return
i2c_transfer
(
chip
,
addr
,
alen
,
buffer
,
len
,
(
alen
?
I2C_M_COMBO
:
I2C_M_READ
));
}
}
/**
/**
...
@@ -346,15 +346,21 @@ int i2c_set_bus_num(unsigned int bus)
...
@@ -346,15 +346,21 @@ int i2c_set_bus_num(unsigned int bus)
{
{
switch
(
bus
)
{
switch
(
bus
)
{
#if CONFIG_SYS_MAX_I2C_BUS > 0
#if CONFIG_SYS_MAX_I2C_BUS > 0
case
0
:
twi
=
(
void
*
)
TWI0_CLKDIV
;
return
0
;
case
0
:
twi
=
(
void
*
)
TWI0_CLKDIV
;
return
0
;
#endif
#endif
#if CONFIG_SYS_MAX_I2C_BUS > 1
#if CONFIG_SYS_MAX_I2C_BUS > 1
case
1
:
twi
=
(
void
*
)
TWI1_CLKDIV
;
return
0
;
case
1
:
twi
=
(
void
*
)
TWI1_CLKDIV
;
return
0
;
#endif
#endif
#if CONFIG_SYS_MAX_I2C_BUS > 2
#if CONFIG_SYS_MAX_I2C_BUS > 2
case
2
:
twi
=
(
void
*
)
TWI2_CLKDIV
;
return
0
;
case
2
:
twi
=
(
void
*
)
TWI2_CLKDIV
;
return
0
;
#endif
#endif
default:
return
-
1
;
default:
return
-
1
;
}
}
}
}
...
@@ -365,14 +371,17 @@ unsigned int i2c_get_bus_num(void)
...
@@ -365,14 +371,17 @@ unsigned int i2c_get_bus_num(void)
{
{
switch
((
unsigned
long
)
twi
)
{
switch
((
unsigned
long
)
twi
)
{
#if CONFIG_SYS_MAX_I2C_BUS > 0
#if CONFIG_SYS_MAX_I2C_BUS > 0
case
TWI0_CLKDIV
:
return
0
;
case
TWI0_CLKDIV
:
return
0
;
#endif
#endif
#if CONFIG_SYS_MAX_I2C_BUS > 1
#if CONFIG_SYS_MAX_I2C_BUS > 1
case
TWI1_CLKDIV
:
return
1
;
case
TWI1_CLKDIV
:
return
1
;
#endif
#endif
#if CONFIG_SYS_MAX_I2C_BUS > 2
#if CONFIG_SYS_MAX_I2C_BUS > 2
case
TWI2_CLKDIV
:
return
2
;
case
TWI2_CLKDIV
:
return
2
;
#endif
#endif
default:
return
-
1
;
default:
return
-
1
;
}
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment