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
968c94bc
Commit
968c94bc
authored
Mar 29, 2015
by
Ralf Baechle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MIPS: SEAD3: Nuke I2C driver that never was wired up in Makefile.
Signed-off-by:
Ralf Baechle
<
ralf@linux-mips.org
>
parent
e598e471
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
0 additions
and
397 deletions
+0
-397
arch/mips/mti-sead3/sead3-i2c-drv.c
arch/mips/mti-sead3/sead3-i2c-drv.c
+0
-397
No files found.
arch/mips/mti-sead3/sead3-i2c-drv.c
deleted
100644 → 0
View file @
e598e471
/*
* 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) 2012 MIPS Technologies, Inc. All rights reserved.
* Copyright (C) 2015 Imagination Technologies, Inc.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <asm/mips-boards/sead3-addr.h>
#define PIC32_I2CxCON 0x0000
#define PIC32_I2CCON_ON (1<<15)
#define PIC32_I2CCON_ACKDT (1<<5)
#define PIC32_I2CCON_ACKEN (1<<4)
#define PIC32_I2CCON_RCEN (1<<3)
#define PIC32_I2CCON_PEN (1<<2)
#define PIC32_I2CCON_RSEN (1<<1)
#define PIC32_I2CCON_SEN (1<<0)
#define PIC32_I2CxCONCLR 0x0004
#define PIC32_I2CxCONSET 0x0008
#define PIC32_I2CxSTAT 0x0010
#define PIC32_I2CxSTATCLR 0x0014
#define PIC32_I2CSTAT_ACKSTAT (1<<15)
#define PIC32_I2CSTAT_TRSTAT (1<<14)
#define PIC32_I2CSTAT_BCL (1<<10)
#define PIC32_I2CSTAT_IWCOL (1<<7)
#define PIC32_I2CSTAT_I2COV (1<<6)
#define PIC32_I2CxBRG 0x0040
#define PIC32_I2CxTRN 0x0050
#define PIC32_I2CxRCV 0x0060
static
DEFINE_SPINLOCK
(
pic32_bus_lock
);
static
void
__iomem
*
bus_xfer
=
(
void
__iomem
*
)
SEAD3_PIC32_REGISTERS
;
static
void
__iomem
*
bus_status
=
(
void
__iomem
*
)
SEAD3_PI_PIC32_USB_STATUS
;
#define DELAY() udelay(100)
static
inline
unsigned
int
ioready
(
void
)
{
return
readl
(
bus_status
)
&
SEAD3_PI_PIC32_USB_STATUS_IO_RDY
;
}
static
inline
void
wait_ioready
(
void
)
{
do
{
}
while
(
!
ioready
());
}
static
inline
void
wait_ioclear
(
void
)
{
do
{
}
while
(
ioready
());
}
static
inline
void
check_ioclear
(
void
)
{
if
(
ioready
())
{
do
{
(
void
)
readl
(
bus_xfer
);
DELAY
();
}
while
(
ioready
());
}
}
static
u32
pic32_bus_readl
(
u32
reg
)
{
unsigned
long
flags
;
u32
status
,
val
;
spin_lock_irqsave
(
&
pic32_bus_lock
,
flags
);
check_ioclear
();
writel
((
0x01
<<
24
)
|
(
reg
&
0x00ffffff
),
bus_xfer
);
DELAY
();
wait_ioready
();
status
=
readl
(
bus_xfer
);
DELAY
();
val
=
readl
(
bus_xfer
);
wait_ioclear
();
spin_unlock_irqrestore
(
&
pic32_bus_lock
,
flags
);
return
val
;
}
static
void
pic32_bus_writel
(
u32
val
,
u32
reg
)
{
unsigned
long
flags
;
u32
status
;
spin_lock_irqsave
(
&
pic32_bus_lock
,
flags
);
check_ioclear
();
writel
((
0x10
<<
24
)
|
(
reg
&
0x00ffffff
),
bus_xfer
);
DELAY
();
writel
(
val
,
bus_xfer
);
DELAY
();
wait_ioready
();
status
=
readl
(
bus_xfer
);
wait_ioclear
();
spin_unlock_irqrestore
(
&
pic32_bus_lock
,
flags
);
}
struct
pic32_i2c_platform_data
{
u32
base
;
struct
i2c_adapter
adap
;
u32
xfer_timeout
;
u32
ack_timeout
;
u32
ctl_timeout
;
};
static
inline
void
pic32_i2c_start
(
struct
pic32_i2c_platform_data
*
adap
)
{
pic32_bus_writel
(
PIC32_I2CCON_SEN
,
adap
->
base
+
PIC32_I2CxCONSET
);
}
static
inline
void
pic32_i2c_stop
(
struct
pic32_i2c_platform_data
*
adap
)
{
pic32_bus_writel
(
PIC32_I2CCON_PEN
,
adap
->
base
+
PIC32_I2CxCONSET
);
}
static
inline
void
pic32_i2c_ack
(
struct
pic32_i2c_platform_data
*
adap
)
{
pic32_bus_writel
(
PIC32_I2CCON_ACKDT
,
adap
->
base
+
PIC32_I2CxCONCLR
);
pic32_bus_writel
(
PIC32_I2CCON_ACKEN
,
adap
->
base
+
PIC32_I2CxCONSET
);
}
static
inline
void
pic32_i2c_nack
(
struct
pic32_i2c_platform_data
*
adap
)
{
pic32_bus_writel
(
PIC32_I2CCON_ACKDT
,
adap
->
base
+
PIC32_I2CxCONSET
);
pic32_bus_writel
(
PIC32_I2CCON_ACKEN
,
adap
->
base
+
PIC32_I2CxCONSET
);
}
static
inline
int
pic32_i2c_idle
(
struct
pic32_i2c_platform_data
*
adap
)
{
int
i
;
for
(
i
=
0
;
i
<
adap
->
ctl_timeout
;
i
++
)
{
if
(((
pic32_bus_readl
(
adap
->
base
+
PIC32_I2CxCON
)
&
(
PIC32_I2CCON_ACKEN
|
PIC32_I2CCON_RCEN
|
PIC32_I2CCON_PEN
|
PIC32_I2CCON_RSEN
|
PIC32_I2CCON_SEN
))
==
0
)
&&
((
pic32_bus_readl
(
adap
->
base
+
PIC32_I2CxSTAT
)
&
(
PIC32_I2CSTAT_TRSTAT
))
==
0
))
return
0
;
udelay
(
1
);
}
return
-
ETIMEDOUT
;
}
static
inline
u32
pic32_i2c_master_write
(
struct
pic32_i2c_platform_data
*
adap
,
u32
byte
)
{
pic32_bus_writel
(
byte
,
adap
->
base
+
PIC32_I2CxTRN
);
return
pic32_bus_readl
(
adap
->
base
+
PIC32_I2CxSTAT
)
&
PIC32_I2CSTAT_IWCOL
;
}
static
inline
u32
pic32_i2c_master_read
(
struct
pic32_i2c_platform_data
*
adap
)
{
pic32_bus_writel
(
PIC32_I2CCON_RCEN
,
adap
->
base
+
PIC32_I2CxCONSET
);
while
(
pic32_bus_readl
(
adap
->
base
+
PIC32_I2CxCON
)
&
PIC32_I2CCON_RCEN
)
;
pic32_bus_writel
(
PIC32_I2CSTAT_I2COV
,
adap
->
base
+
PIC32_I2CxSTATCLR
);
return
pic32_bus_readl
(
adap
->
base
+
PIC32_I2CxRCV
);
}
static
int
pic32_i2c_address
(
struct
pic32_i2c_platform_data
*
adap
,
unsigned
int
addr
,
int
rd
)
{
pic32_i2c_idle
(
adap
);
pic32_i2c_start
(
adap
);
pic32_i2c_idle
(
adap
);
addr
<<=
1
;
if
(
rd
)
addr
|=
1
;
if
(
pic32_i2c_master_write
(
adap
,
addr
))
return
-
EIO
;
pic32_i2c_idle
(
adap
);
if
(
pic32_bus_readl
(
adap
->
base
+
PIC32_I2CxSTAT
)
&
PIC32_I2CSTAT_ACKSTAT
)
return
-
EIO
;
return
0
;
}
static
int
sead3_i2c_read
(
struct
pic32_i2c_platform_data
*
adap
,
unsigned
char
*
buf
,
unsigned
int
len
)
{
u32
data
;
int
i
;
i
=
0
;
while
(
i
<
len
)
{
data
=
pic32_i2c_master_read
(
adap
);
buf
[
i
++
]
=
data
;
if
(
i
<
len
)
pic32_i2c_ack
(
adap
);
else
pic32_i2c_nack
(
adap
);
}
pic32_i2c_stop
(
adap
);
pic32_i2c_idle
(
adap
);
return
0
;
}
static
int
sead3_i2c_write
(
struct
pic32_i2c_platform_data
*
adap
,
unsigned
char
*
buf
,
unsigned
int
len
)
{
int
i
;
u32
data
;
i
=
0
;
while
(
i
<
len
)
{
data
=
buf
[
i
];
if
(
pic32_i2c_master_write
(
adap
,
data
))
return
-
EIO
;
pic32_i2c_idle
(
adap
);
if
(
pic32_bus_readl
(
adap
->
base
+
PIC32_I2CxSTAT
)
&
PIC32_I2CSTAT_ACKSTAT
)
return
-
EIO
;
i
++
;
}
pic32_i2c_stop
(
adap
);
pic32_i2c_idle
(
adap
);
return
0
;
}
static
int
sead3_pic32_platform_xfer
(
struct
i2c_adapter
*
i2c_adap
,
struct
i2c_msg
*
msgs
,
int
num
)
{
struct
pic32_i2c_platform_data
*
adap
=
i2c_adap
->
algo_data
;
struct
i2c_msg
*
p
;
int
i
,
err
=
0
;
for
(
i
=
0
;
i
<
num
;
i
++
)
{
#define __BUFSIZE 80
int
ii
;
static
char
buf
[
__BUFSIZE
];
char
*
b
=
buf
;
p
=
&
msgs
[
i
];
b
+=
sprintf
(
buf
,
" [%d bytes]"
,
p
->
len
);
if
((
p
->
flags
&
I2C_M_RD
)
==
0
)
{
for
(
ii
=
0
;
ii
<
p
->
len
;
ii
++
)
{
if
(
b
<
&
buf
[
__BUFSIZE
-
4
])
{
b
+=
sprintf
(
b
,
" %02x"
,
p
->
buf
[
ii
]);
}
else
{
strcat
(
b
,
"..."
);
break
;
}
}
}
}
for
(
i
=
0
;
!
err
&&
i
<
num
;
i
++
)
{
p
=
&
msgs
[
i
];
err
=
pic32_i2c_address
(
adap
,
p
->
addr
,
p
->
flags
&
I2C_M_RD
);
if
(
err
||
!
p
->
len
)
continue
;
if
(
p
->
flags
&
I2C_M_RD
)
err
=
sead3_i2c_read
(
adap
,
p
->
buf
,
p
->
len
);
else
err
=
sead3_i2c_write
(
adap
,
p
->
buf
,
p
->
len
);
}
/* Return the number of messages processed, or the error code. */
if
(
err
==
0
)
err
=
num
;
return
err
;
}
static
u32
sead3_pic32_platform_func
(
struct
i2c_adapter
*
adap
)
{
return
I2C_FUNC_I2C
|
I2C_FUNC_SMBUS_EMUL
;
}
static
const
struct
i2c_algorithm
sead3_platform_algo
=
{
.
master_xfer
=
sead3_pic32_platform_xfer
,
.
functionality
=
sead3_pic32_platform_func
,
};
static
void
sead3_i2c_platform_setup
(
struct
pic32_i2c_platform_data
*
priv
)
{
pic32_bus_writel
(
500
,
priv
->
base
+
PIC32_I2CxBRG
);
pic32_bus_writel
(
PIC32_I2CCON_ON
,
priv
->
base
+
PIC32_I2CxCONCLR
);
pic32_bus_writel
(
PIC32_I2CCON_ON
,
priv
->
base
+
PIC32_I2CxCONSET
);
pic32_bus_writel
(
PIC32_I2CSTAT_BCL
|
PIC32_I2CSTAT_IWCOL
,
priv
->
base
+
PIC32_I2CxSTATCLR
);
}
static
int
sead3_i2c_platform_probe
(
struct
platform_device
*
pdev
)
{
struct
pic32_i2c_platform_data
*
priv
;
struct
resource
*
r
;
int
ret
;
r
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
r
)
{
ret
=
-
ENODEV
;
goto
out
;
}
priv
=
kzalloc
(
sizeof
(
struct
pic32_i2c_platform_data
),
GFP_KERNEL
);
if
(
!
priv
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
priv
->
base
=
r
->
start
;
if
(
!
priv
->
base
)
{
ret
=
-
EBUSY
;
goto
out_mem
;
}
priv
->
xfer_timeout
=
200
;
priv
->
ack_timeout
=
200
;
priv
->
ctl_timeout
=
200
;
priv
->
adap
.
nr
=
pdev
->
id
;
priv
->
adap
.
algo
=
&
sead3_platform_algo
;
priv
->
adap
.
algo_data
=
priv
;
priv
->
adap
.
dev
.
parent
=
&
pdev
->
dev
;
strlcpy
(
priv
->
adap
.
name
,
"SEAD3 PIC32"
,
sizeof
(
priv
->
adap
.
name
));
sead3_i2c_platform_setup
(
priv
);
ret
=
i2c_add_numbered_adapter
(
&
priv
->
adap
);
if
(
ret
==
0
)
{
platform_set_drvdata
(
pdev
,
priv
);
return
0
;
}
out_mem:
kfree
(
priv
);
out:
return
ret
;
}
static
int
sead3_i2c_platform_remove
(
struct
platform_device
*
pdev
)
{
struct
pic32_i2c_platform_data
*
priv
=
platform_get_drvdata
(
pdev
);
platform_set_drvdata
(
pdev
,
NULL
);
i2c_del_adapter
(
&
priv
->
adap
);
kfree
(
priv
);
return
0
;
}
#ifdef CONFIG_PM
static
int
sead3_i2c_platform_suspend
(
struct
platform_device
*
pdev
,
pm_message_t
state
)
{
dev_dbg
(
&
pdev
->
dev
,
"i2c_platform_disable
\n
"
);
return
0
;
}
static
int
sead3_i2c_platform_resume
(
struct
platform_device
*
pdev
)
{
struct
pic32_i2c_platform_data
*
priv
=
platform_get_drvdata
(
pdev
);
dev_dbg
(
&
pdev
->
dev
,
"sead3_i2c_platform_setup
\n
"
);
sead3_i2c_platform_setup
(
priv
);
return
0
;
}
#else
#define sead3_i2c_platform_suspend NULL
#define sead3_i2c_platform_resume NULL
#endif
static
struct
platform_driver
sead3_i2c_platform_driver
=
{
.
driver
=
{
.
name
=
"sead3-i2c"
,
},
.
probe
=
sead3_i2c_platform_probe
,
.
remove
=
sead3_i2c_platform_remove
,
.
suspend
=
sead3_i2c_platform_suspend
,
.
resume
=
sead3_i2c_platform_resume
,
};
module_platform_driver
(
sead3_i2c_platform_driver
);
MODULE_AUTHOR
(
"Chris Dearman, MIPS Technologies INC."
);
MODULE_DESCRIPTION
(
"SEAD3 PIC32 I2C driver"
);
MODULE_LICENSE
(
"GPL"
);
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