Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
81306d53
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
81306d53
编写于
2月 08, 2015
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'spi/topic/sh-msiof' into spi-next
上级
f69c22ed
19f0ad09
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
84 addition
and
25 deletion
+84
-25
Documentation/devicetree/bindings/spi/sh-msiof.txt
Documentation/devicetree/bindings/spi/sh-msiof.txt
+16
-0
drivers/spi/spi-sh-msiof.c
drivers/spi/spi-sh-msiof.c
+66
-25
include/linux/spi/sh_msiof.h
include/linux/spi/sh_msiof.h
+2
-0
未找到文件。
Documentation/devicetree/bindings/spi/sh-msiof.txt
浏览文件 @
81306d53
...
...
@@ -30,6 +30,22 @@ Optional properties:
specifiers, one for transmission, and one for
reception.
- dma-names : Must contain a list of two DMA names, "tx" and "rx".
- renesas,dtdl : delay sync signal (setup) in transmit mode.
Must contain one of the following values:
0 (no bit delay)
50 (0.5-clock-cycle delay)
100 (1-clock-cycle delay)
150 (1.5-clock-cycle delay)
200 (2-clock-cycle delay)
- renesas,syncdl : delay sync signal (hold) in transmit mode.
Must contain one of the following values:
0 (no bit delay)
50 (0.5-clock-cycle delay)
100 (1-clock-cycle delay)
150 (1.5-clock-cycle delay)
200 (2-clock-cycle delay)
300 (3-clock-cycle delay)
Optional properties, deprecated for soctype-specific bindings:
- renesas,tx-fifo-size : Overrides the default tx fifo size given in words
...
...
drivers/spi/spi-sh-msiof.c
浏览文件 @
81306d53
...
...
@@ -82,6 +82,8 @@ struct sh_msiof_spi_priv {
#define MDR1_SYNCMD_LR 0x30000000
/* L/R mode */
#define MDR1_SYNCAC_SHIFT 25
/* Sync Polarity (1 = Active-low) */
#define MDR1_BITLSB_SHIFT 24
/* MSB/LSB First (1 = LSB first) */
#define MDR1_DTDL_SHIFT 20
/* Data Pin Bit Delay for MSIOF_SYNC */
#define MDR1_SYNCDL_SHIFT 16
/* Frame Sync Signal Timing Delay */
#define MDR1_FLD_MASK 0x0000000c
/* Frame Sync Signal Interval (0-3) */
#define MDR1_FLD_SHIFT 2
#define MDR1_XXSTP 0x00000001
/* Transmission/Reception Stop on FIFO */
...
...
@@ -241,42 +243,80 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
static
struct
{
unsigned
short
div
;
unsigned
short
scr
;
}
const
sh_msiof_spi_clk_table
[]
=
{
{
1
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_1
},
{
2
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_2
},
{
4
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_4
},
{
8
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_8
},
{
16
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_16
},
{
32
,
SCR_BRPS
(
1
)
|
SCR_BRDV_DIV_32
},
{
64
,
SCR_BRPS
(
32
)
|
SCR_BRDV_DIV_2
},
{
128
,
SCR_BRPS
(
32
)
|
SCR_BRDV_DIV_4
},
{
256
,
SCR_BRPS
(
32
)
|
SCR_BRDV_DIV_8
},
{
512
,
SCR_BRPS
(
32
)
|
SCR_BRDV_DIV_16
},
{
1024
,
SCR_BRPS
(
32
)
|
SCR_BRDV_DIV_32
},
unsigned
short
brdv
;
}
const
sh_msiof_spi_div_table
[]
=
{
{
1
,
SCR_BRDV_DIV_1
},
{
2
,
SCR_BRDV_DIV_2
},
{
4
,
SCR_BRDV_DIV_4
},
{
8
,
SCR_BRDV_DIV_8
},
{
16
,
SCR_BRDV_DIV_16
},
{
32
,
SCR_BRDV_DIV_32
},
};
static
void
sh_msiof_spi_set_clk_regs
(
struct
sh_msiof_spi_priv
*
p
,
unsigned
long
parent_rate
,
u32
spi_hz
)
{
unsigned
long
div
=
1024
;
u32
brps
,
scr
;
size_t
k
;
if
(
!
WARN_ON
(
!
spi_hz
||
!
parent_rate
))
div
=
DIV_ROUND_UP
(
parent_rate
,
spi_hz
);
/* TODO: make more fine grained */
for
(
k
=
0
;
k
<
ARRAY_SIZE
(
sh_msiof_spi_clk_table
);
k
++
)
{
if
(
sh_msiof_spi_clk_table
[
k
].
div
>=
div
)
for
(
k
=
0
;
k
<
ARRAY_SIZE
(
sh_msiof_spi_div_table
);
k
++
)
{
brps
=
DIV_ROUND_UP
(
div
,
sh_msiof_spi_div_table
[
k
].
div
);
if
(
brps
<=
32
)
/* max of brdv is 32 */
break
;
}
k
=
min_t
(
int
,
k
,
ARRAY_SIZE
(
sh_msiof_spi_
clk
_table
)
-
1
);
k
=
min_t
(
int
,
k
,
ARRAY_SIZE
(
sh_msiof_spi_
div
_table
)
-
1
);
sh_msiof_write
(
p
,
TSCR
,
sh_msiof_spi_clk_table
[
k
].
scr
);
scr
=
sh_msiof_spi_div_table
[
k
].
brdv
|
SCR_BRPS
(
brps
);
sh_msiof_write
(
p
,
TSCR
,
scr
);
if
(
!
(
p
->
chipdata
->
master_flags
&
SPI_MASTER_MUST_TX
))
sh_msiof_write
(
p
,
RSCR
,
sh_msiof_spi_clk_table
[
k
].
scr
);
sh_msiof_write
(
p
,
RSCR
,
scr
);
}
static
u32
sh_msiof_get_delay_bit
(
u32
dtdl_or_syncdl
)
{
/*
* DTDL/SYNCDL bit : p->info->dtdl or p->info->syncdl
* b'000 : 0
* b'001 : 100
* b'010 : 200
* b'011 (SYNCDL only) : 300
* b'101 : 50
* b'110 : 150
*/
if
(
dtdl_or_syncdl
%
100
)
return
dtdl_or_syncdl
/
100
+
5
;
else
return
dtdl_or_syncdl
/
100
;
}
static
u32
sh_msiof_spi_get_dtdl_and_syncdl
(
struct
sh_msiof_spi_priv
*
p
)
{
u32
val
;
if
(
!
p
->
info
)
return
0
;
/* check if DTDL and SYNCDL is allowed value */
if
(
p
->
info
->
dtdl
>
200
||
p
->
info
->
syncdl
>
300
)
{
dev_warn
(
&
p
->
pdev
->
dev
,
"DTDL or SYNCDL is too large
\n
"
);
return
0
;
}
/* check if the sum of DTDL and SYNCDL becomes an integer value */
if
((
p
->
info
->
dtdl
+
p
->
info
->
syncdl
)
%
100
)
{
dev_warn
(
&
p
->
pdev
->
dev
,
"the sum of DTDL/SYNCDL is not good
\n
"
);
return
0
;
}
val
=
sh_msiof_get_delay_bit
(
p
->
info
->
dtdl
)
<<
MDR1_DTDL_SHIFT
;
val
|=
sh_msiof_get_delay_bit
(
p
->
info
->
syncdl
)
<<
MDR1_SYNCDL_SHIFT
;
return
val
;
}
static
void
sh_msiof_spi_set_pin_regs
(
struct
sh_msiof_spi_priv
*
p
,
...
...
@@ -296,6 +336,7 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p,
tmp
=
MDR1_SYNCMD_SPI
|
1
<<
MDR1_FLD_SHIFT
|
MDR1_XXSTP
;
tmp
|=
!
cs_high
<<
MDR1_SYNCAC_SHIFT
;
tmp
|=
lsb_first
<<
MDR1_BITLSB_SHIFT
;
tmp
|=
sh_msiof_spi_get_dtdl_and_syncdl
(
p
);
sh_msiof_write
(
p
,
TMDR1
,
tmp
|
MDR1_TRMD
|
TMDR1_PCON
);
if
(
p
->
chipdata
->
master_flags
&
SPI_MASTER_MUST_TX
)
{
/* These bits are reserved if RX needs TX */
...
...
@@ -501,7 +542,7 @@ static int sh_msiof_spi_setup(struct spi_device *spi)
gpio_set_value
(
spi
->
cs_gpio
,
!
(
spi
->
mode
&
SPI_CS_HIGH
));
pm_runtime_put
_sync
(
&
p
->
pdev
->
dev
);
pm_runtime_put
(
&
p
->
pdev
->
dev
);
return
0
;
}
...
...
@@ -595,8 +636,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
}
/* wait for tx fifo to be emptied / rx fifo to be filled */
ret
=
wait_for_completion_timeout
(
&
p
->
done
,
HZ
);
if
(
!
ret
)
{
if
(
!
wait_for_completion_timeout
(
&
p
->
done
,
HZ
))
{
dev_err
(
&
p
->
pdev
->
dev
,
"PIO timeout
\n
"
);
ret
=
-
ETIMEDOUT
;
goto
stop_reset
;
...
...
@@ -706,8 +746,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
}
/* wait for tx fifo to be emptied / rx fifo to be filled */
ret
=
wait_for_completion_timeout
(
&
p
->
done
,
HZ
);
if
(
!
ret
)
{
if
(
!
wait_for_completion_timeout
(
&
p
->
done
,
HZ
))
{
dev_err
(
&
p
->
pdev
->
dev
,
"DMA timeout
\n
"
);
ret
=
-
ETIMEDOUT
;
goto
stop_reset
;
...
...
@@ -957,6 +996,8 @@ static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev)
&
info
->
tx_fifo_override
);
of_property_read_u32
(
np
,
"renesas,rx-fifo-size"
,
&
info
->
rx_fifo_override
);
of_property_read_u32
(
np
,
"renesas,dtdl"
,
&
info
->
dtdl
);
of_property_read_u32
(
np
,
"renesas,syncdl"
,
&
info
->
syncdl
);
info
->
num_chipselect
=
num_cs
;
...
...
include/linux/spi/sh_msiof.h
浏览文件 @
81306d53
...
...
@@ -7,6 +7,8 @@ struct sh_msiof_spi_info {
u16
num_chipselect
;
unsigned
int
dma_tx_id
;
unsigned
int
dma_rx_id
;
u32
dtdl
;
u32
syncdl
;
};
#endif
/* __SPI_SH_MSIOF_H__ */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录