Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
968c94bc
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
968c94bc
编写于
3月 29, 2015
作者:
R
Ralf Baechle
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
MIPS: SEAD3: Nuke I2C driver that never was wired up in Makefile.
Signed-off-by:
N
Ralf Baechle
<
ralf@linux-mips.org
>
上级
e598e471
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
0 addition
and
397 deletion
+0
-397
arch/mips/mti-sead3/sead3-i2c-drv.c
arch/mips/mti-sead3/sead3-i2c-drv.c
+0
-397
未找到文件。
arch/mips/mti-sead3/sead3-i2c-drv.c
已删除
100644 → 0
浏览文件 @
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"
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录