Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
45b15d98
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,发现更多精彩内容 >>
提交
45b15d98
编写于
3月 30, 2014
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branches 'spi/topic/xilinx' and 'spi/topic/xtfpga' into spi-next
上级
b1ad487c
6ff8672a
be8dde46
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
205 addition
and
20 deletion
+205
-20
Documentation/devicetree/bindings/spi/spi-xtensa-xtfpga.txt
Documentation/devicetree/bindings/spi/spi-xtensa-xtfpga.txt
+9
-0
MAINTAINERS
MAINTAINERS
+6
-0
drivers/spi/Kconfig
drivers/spi/Kconfig
+13
-0
drivers/spi/Makefile
drivers/spi/Makefile
+1
-0
drivers/spi/spi-xilinx.c
drivers/spi/spi-xilinx.c
+6
-20
drivers/spi/spi-xtensa-xtfpga.c
drivers/spi/spi-xtensa-xtfpga.c
+170
-0
未找到文件。
Documentation/devicetree/bindings/spi/spi-xtensa-xtfpga.txt
0 → 100644
浏览文件 @
45b15d98
Cadence Xtensa XTFPGA platform SPI controller.
This simple SPI master controller is built into xtfpga bitstreams and is used
to control daughterboard audio codec.
Required properties:
- compatible: should be "cdns,xtfpga-spi".
- reg: physical base address of the controller and length of memory mapped
region.
MAINTAINERS
浏览文件 @
45b15d98
...
...
@@ -9782,6 +9782,12 @@ L: linux-serial@vger.kernel.org
S: Maintained
F: drivers/tty/serial/uartlite.c
XTENSA XTFPGA PLATFORM SUPPORT
M: Max Filippov <jcmvbkbc@gmail.com>
L: linux-xtensa@linux-xtensa.org
S: Maintained
F: drivers/spi/spi-xtensa-xtfpga.c
YAM DRIVER FOR AX.25
M: Jean-Paul Roubelat <jpr@f6fbb.org>
L: linux-hams@vger.kernel.org
...
...
drivers/spi/Kconfig
浏览文件 @
45b15d98
...
...
@@ -538,6 +538,19 @@ config SPI_XILINX
Or for the DS570, see "XPS Serial Peripheral Interface (SPI) (v2.00b)"
config SPI_XTENSA_XTFPGA
tristate "Xtensa SPI controller for xtfpga"
depends on (XTENSA && XTENSA_PLATFORM_XTFPGA) || COMPILE_TEST
select SPI_BITBANG
help
SPI driver for xtfpga SPI master controller.
This simple SPI master controller is built into xtfpga bitstreams
and is used to control daughterboard audio codec. It always transfers
16 bit words in SPI mode 0, automatically asserting CS on transfer
start and deasserting on end.
config SPI_NUC900
tristate "Nuvoton NUC900 series SPI"
depends on ARCH_W90X900
...
...
drivers/spi/Makefile
浏览文件 @
45b15d98
...
...
@@ -81,3 +81,4 @@ obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o
obj-$(CONFIG_SPI_TXX9)
+=
spi-txx9.o
obj-$(CONFIG_SPI_XCOMM)
+=
spi-xcomm.o
obj-$(CONFIG_SPI_XILINX)
+=
spi-xilinx.o
obj-$(CONFIG_SPI_XTENSA_XTFPGA)
+=
spi-xtensa-xtfpga.o
drivers/spi/spi-xilinx.c
浏览文件 @
45b15d98
...
...
@@ -87,10 +87,10 @@ struct xilinx_spi {
const
u8
*
tx_ptr
;
/* pointer in the Rx buffer */
int
remaining_bytes
;
/* the number of bytes left to transfer */
u8
bits_per_word
;
unsigned
int
(
*
read_fn
)
(
void
__iomem
*
);
void
(
*
write_fn
)
(
u32
,
void
__iomem
*
);
void
(
*
tx_fn
)
(
struct
xilinx_spi
*
);
void
(
*
rx_fn
)
(
struct
xilinx_spi
*
);
unsigned
int
(
*
read_fn
)(
void
__iomem
*
);
void
(
*
write_fn
)(
u32
,
void
__iomem
*
);
void
(
*
tx_fn
)(
struct
xilinx_spi
*
);
void
(
*
rx_fn
)(
struct
xilinx_spi
*
);
};
static
void
xspi_write32
(
u32
val
,
void
__iomem
*
addr
)
...
...
@@ -208,26 +208,11 @@ static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
}
/* spi_bitbang requires custom setup_transfer() to be defined if there is a
* custom txrx_bufs(). We have nothing to setup here as the SPI IP block
* supports 8 or 16 bits per word which cannot be changed in software.
* SPI clock can't be changed in software either.
* Check for correct bits per word. Chip select delay calculations could be
* added here as soon as bitbang_work() can be made aware of the delay value.
* custom txrx_bufs().
*/
static
int
xilinx_spi_setup_transfer
(
struct
spi_device
*
spi
,
struct
spi_transfer
*
t
)
{
struct
xilinx_spi
*
xspi
=
spi_master_get_devdata
(
spi
->
master
);
u8
bits_per_word
;
bits_per_word
=
(
t
&&
t
->
bits_per_word
)
?
t
->
bits_per_word
:
spi
->
bits_per_word
;
if
(
bits_per_word
!=
xspi
->
bits_per_word
)
{
dev_err
(
&
spi
->
dev
,
"%s, unsupported bits_per_word=%d
\n
"
,
__func__
,
bits_per_word
);
return
-
EINVAL
;
}
return
0
;
}
...
...
@@ -406,6 +391,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)
xspi
->
write_fn
=
xspi_write32_be
;
}
master
->
bits_per_word_mask
=
SPI_BPW_MASK
(
bits_per_word
);
xspi
->
bits_per_word
=
bits_per_word
;
if
(
xspi
->
bits_per_word
==
8
)
{
xspi
->
tx_fn
=
xspi_tx8
;
...
...
drivers/spi/spi-xtensa-xtfpga.c
0 → 100644
浏览文件 @
45b15d98
/*
* Xtensa xtfpga SPI controller driver
*
* Copyright (c) 2014 Cadence Design Systems Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#define XTFPGA_SPI_NAME "xtfpga_spi"
#define XTFPGA_SPI_START 0x0
#define XTFPGA_SPI_BUSY 0x4
#define XTFPGA_SPI_DATA 0x8
#define BUSY_WAIT_US 100
struct
xtfpga_spi
{
struct
spi_bitbang
bitbang
;
void
__iomem
*
regs
;
u32
data
;
unsigned
data_sz
;
};
static
inline
void
xtfpga_spi_write32
(
const
struct
xtfpga_spi
*
spi
,
unsigned
addr
,
u32
val
)
{
iowrite32
(
val
,
spi
->
regs
+
addr
);
}
static
inline
unsigned
int
xtfpga_spi_read32
(
const
struct
xtfpga_spi
*
spi
,
unsigned
addr
)
{
return
ioread32
(
spi
->
regs
+
addr
);
}
static
inline
void
xtfpga_spi_wait_busy
(
struct
xtfpga_spi
*
xspi
)
{
unsigned
i
;
for
(
i
=
0
;
xtfpga_spi_read32
(
xspi
,
XTFPGA_SPI_BUSY
)
&&
i
<
BUSY_WAIT_US
;
++
i
)
udelay
(
1
);
WARN_ON_ONCE
(
i
==
BUSY_WAIT_US
);
}
static
u32
xtfpga_spi_txrx_word
(
struct
spi_device
*
spi
,
unsigned
nsecs
,
u32
v
,
u8
bits
)
{
struct
xtfpga_spi
*
xspi
=
spi_master_get_devdata
(
spi
->
master
);
xspi
->
data
=
(
xspi
->
data
<<
bits
)
|
(
v
&
GENMASK
(
bits
-
1
,
0
));
xspi
->
data_sz
+=
bits
;
if
(
xspi
->
data_sz
>=
16
)
{
xtfpga_spi_write32
(
xspi
,
XTFPGA_SPI_DATA
,
xspi
->
data
>>
(
xspi
->
data_sz
-
16
));
xspi
->
data_sz
-=
16
;
xtfpga_spi_write32
(
xspi
,
XTFPGA_SPI_START
,
1
);
xtfpga_spi_wait_busy
(
xspi
);
xtfpga_spi_write32
(
xspi
,
XTFPGA_SPI_START
,
0
);
}
return
0
;
}
static
void
xtfpga_spi_chipselect
(
struct
spi_device
*
spi
,
int
is_on
)
{
struct
xtfpga_spi
*
xspi
=
spi_master_get_devdata
(
spi
->
master
);
WARN_ON
(
xspi
->
data_sz
!=
0
);
xspi
->
data_sz
=
0
;
}
static
int
xtfpga_spi_probe
(
struct
platform_device
*
pdev
)
{
struct
xtfpga_spi
*
xspi
;
struct
resource
*
mem
;
int
ret
;
struct
spi_master
*
master
;
master
=
spi_alloc_master
(
&
pdev
->
dev
,
sizeof
(
struct
xtfpga_spi
));
if
(
!
master
)
return
-
ENOMEM
;
master
->
flags
=
SPI_MASTER_NO_RX
;
master
->
bits_per_word_mask
=
SPI_BPW_RANGE_MASK
(
1
,
16
);
master
->
bus_num
=
pdev
->
dev
.
id
;
master
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
xspi
=
spi_master_get_devdata
(
master
);
xspi
->
bitbang
.
master
=
master
;
xspi
->
bitbang
.
chipselect
=
xtfpga_spi_chipselect
;
xspi
->
bitbang
.
txrx_word
[
SPI_MODE_0
]
=
xtfpga_spi_txrx_word
;
mem
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
mem
)
{
dev_err
(
&
pdev
->
dev
,
"No memory resource
\n
"
);
ret
=
-
ENODEV
;
goto
err
;
}
xspi
->
regs
=
devm_ioremap_resource
(
&
pdev
->
dev
,
mem
);
if
(
IS_ERR
(
xspi
->
regs
))
{
ret
=
PTR_ERR
(
xspi
->
regs
);
goto
err
;
}
xtfpga_spi_write32
(
xspi
,
XTFPGA_SPI_START
,
0
);
usleep_range
(
1000
,
2000
);
if
(
xtfpga_spi_read32
(
xspi
,
XTFPGA_SPI_BUSY
))
{
dev_err
(
&
pdev
->
dev
,
"Device stuck in busy state
\n
"
);
ret
=
-
EBUSY
;
goto
err
;
}
ret
=
spi_bitbang_start
(
&
xspi
->
bitbang
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"spi_bitbang_start failed
\n
"
);
goto
err
;
}
platform_set_drvdata
(
pdev
,
master
);
return
0
;
err:
spi_master_put
(
master
);
return
ret
;
}
static
int
xtfpga_spi_remove
(
struct
platform_device
*
pdev
)
{
struct
spi_master
*
master
=
platform_get_drvdata
(
pdev
);
struct
xtfpga_spi
*
xspi
=
spi_master_get_devdata
(
master
);
spi_bitbang_stop
(
&
xspi
->
bitbang
);
spi_master_put
(
master
);
return
0
;
}
MODULE_ALIAS
(
"platform:"
XTFPGA_SPI_NAME
);
#ifdef CONFIG_OF
static
const
struct
of_device_id
xtfpga_spi_of_match
[]
=
{
{
.
compatible
=
"cdns,xtfpga-spi"
,
},
{}
};
MODULE_DEVICE_TABLE
(
of
,
xtfpga_spi_of_match
);
#endif
static
struct
platform_driver
xtfpga_spi_driver
=
{
.
probe
=
xtfpga_spi_probe
,
.
remove
=
xtfpga_spi_remove
,
.
driver
=
{
.
name
=
XTFPGA_SPI_NAME
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
of_match_ptr
(
xtfpga_spi_of_match
),
},
};
module_platform_driver
(
xtfpga_spi_driver
);
MODULE_AUTHOR
(
"Max Filippov <jcmvbkbc@gmail.com>"
);
MODULE_DESCRIPTION
(
"xtensa xtfpga SPI driver"
);
MODULE_LICENSE
(
"GPL"
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录