Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
21e34a33
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
21e34a33
编写于
8月 23, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'spi/topic/quad' into spi-qspi
上级
505a1495
db90a441
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
144 addition
and
3 deletion
+144
-3
drivers/spi/spi.c
drivers/spi/spi.c
+118
-1
include/linux/spi/spi.h
include/linux/spi/spi.h
+26
-2
未找到文件。
drivers/spi/spi.c
浏览文件 @
21e34a33
...
...
@@ -885,6 +885,51 @@ static void of_register_spi_devices(struct spi_master *master)
if
(
of_find_property
(
nc
,
"spi-3wire"
,
NULL
))
spi
->
mode
|=
SPI_3WIRE
;
/* Device DUAL/QUAD mode */
prop
=
of_get_property
(
nc
,
"spi-tx-nbits"
,
&
len
);
if
(
!
prop
||
len
<
sizeof
(
*
prop
))
{
dev_err
(
&
master
->
dev
,
"%s has no 'spi-tx-nbits' property
\n
"
,
nc
->
full_name
);
spi_dev_put
(
spi
);
continue
;
}
switch
(
be32_to_cpup
(
prop
))
{
case
SPI_NBITS_SINGLE
:
break
;
case
SPI_NBITS_DUAL
:
spi
->
mode
|=
SPI_TX_DUAL
;
break
;
case
SPI_NBITS_QUAD
:
spi
->
mode
|=
SPI_TX_QUAD
;
break
;
default:
dev_err
(
&
master
->
dev
,
"spi-tx-nbits value is not supported
\n
"
);
spi_dev_put
(
spi
);
continue
;
}
prop
=
of_get_property
(
nc
,
"spi-rx-nbits"
,
&
len
);
if
(
!
prop
||
len
<
sizeof
(
*
prop
))
{
dev_err
(
&
master
->
dev
,
"%s has no 'spi-rx-nbits' property
\n
"
,
nc
->
full_name
);
spi_dev_put
(
spi
);
continue
;
}
switch
(
be32_to_cpup
(
prop
))
{
case
SPI_NBITS_SINGLE
:
break
;
case
SPI_NBITS_DUAL
:
spi
->
mode
|=
SPI_RX_DUAL
;
break
;
case
SPI_NBITS_QUAD
:
spi
->
mode
|=
SPI_RX_QUAD
;
break
;
default:
dev_err
(
&
master
->
dev
,
"spi-rx-nbits value is not supported
\n
"
);
spi_dev_put
(
spi
);
continue
;
}
/* Device speed */
prop
=
of_get_property
(
nc
,
"spi-max-frequency"
,
&
len
);
if
(
!
prop
||
len
<
sizeof
(
*
prop
))
{
...
...
@@ -1332,6 +1377,19 @@ int spi_setup(struct spi_device *spi)
unsigned
bad_bits
;
int
status
=
0
;
/* check mode to prevent that DUAL and QUAD set at the same time
*/
if
(((
spi
->
mode
&
SPI_TX_DUAL
)
&&
(
spi
->
mode
&
SPI_TX_QUAD
))
||
((
spi
->
mode
&
SPI_RX_DUAL
)
&&
(
spi
->
mode
&
SPI_RX_QUAD
)))
{
dev_err
(
&
spi
->
dev
,
"setup: can not select dual and quad at the same time
\n
"
);
return
-
EINVAL
;
}
/* if it is SPI_3WIRE mode, DUAL and QUAD should be forbidden
*/
if
((
spi
->
mode
&
SPI_3WIRE
)
&&
(
spi
->
mode
&
(
SPI_TX_DUAL
|
SPI_TX_QUAD
|
SPI_RX_DUAL
|
SPI_RX_QUAD
)))
return
-
EINVAL
;
/* help drivers fail *cleanly* when they need options
* that aren't supported with their current master
*/
...
...
@@ -1367,6 +1425,11 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
struct
spi_master
*
master
=
spi
->
master
;
struct
spi_transfer
*
xfer
;
if
(
list_empty
(
&
message
->
transfers
))
return
-
EINVAL
;
if
(
!
message
->
complete
)
return
-
EINVAL
;
/* Half-duplex links include original MicroWire, and ones with
* only one data pin like SPI_3WIRE (switches direction) or where
* either MOSI or MISO is missing. They can also be caused by
...
...
@@ -1389,12 +1452,19 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
/**
* Set transfer bits_per_word and max speed as spi device default if
* it is not set for this transfer.
* Set transfer tx_nbits and rx_nbits as single transfer default
* (SPI_NBITS_SINGLE) if it is not set for this transfer.
*/
list_for_each_entry
(
xfer
,
&
message
->
transfers
,
transfer_list
)
{
if
(
!
xfer
->
bits_per_word
)
xfer
->
bits_per_word
=
spi
->
bits_per_word
;
if
(
!
xfer
->
speed_hz
)
if
(
!
xfer
->
speed_hz
)
{
xfer
->
speed_hz
=
spi
->
max_speed_hz
;
if
(
master
->
max_speed_hz
&&
xfer
->
speed_hz
>
master
->
max_speed_hz
)
xfer
->
speed_hz
=
master
->
max_speed_hz
;
}
if
(
master
->
bits_per_word_mask
)
{
/* Only 32 bits fit in the mask */
if
(
xfer
->
bits_per_word
>
32
)
...
...
@@ -1403,6 +1473,53 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
BIT
(
xfer
->
bits_per_word
-
1
)))
return
-
EINVAL
;
}
if
(
xfer
->
speed_hz
&&
master
->
min_speed_hz
&&
xfer
->
speed_hz
<
master
->
min_speed_hz
)
return
-
EINVAL
;
if
(
xfer
->
speed_hz
&&
master
->
max_speed_hz
&&
xfer
->
speed_hz
>
master
->
max_speed_hz
)
if
(
xfer
->
tx_buf
&&
!
xfer
->
tx_nbits
)
xfer
->
tx_nbits
=
SPI_NBITS_SINGLE
;
if
(
xfer
->
rx_buf
&&
!
xfer
->
rx_nbits
)
xfer
->
rx_nbits
=
SPI_NBITS_SINGLE
;
/* check transfer tx/rx_nbits:
* 1. keep the value is not out of single, dual and quad
* 2. keep tx/rx_nbits is contained by mode in spi_device
* 3. if SPI_3WIRE, tx/rx_nbits should be in single
*/
if
(
xfer
->
tx_buf
)
{
if
(
xfer
->
tx_nbits
!=
SPI_NBITS_SINGLE
&&
xfer
->
tx_nbits
!=
SPI_NBITS_DUAL
&&
xfer
->
tx_nbits
!=
SPI_NBITS_QUAD
)
return
-
EINVAL
;
if
((
xfer
->
tx_nbits
==
SPI_NBITS_DUAL
)
&&
!
(
spi
->
mode
&
(
SPI_TX_DUAL
|
SPI_TX_QUAD
)))
return
-
EINVAL
;
if
((
xfer
->
tx_nbits
==
SPI_NBITS_QUAD
)
&&
!
(
spi
->
mode
&
SPI_TX_QUAD
))
return
-
EINVAL
;
if
((
spi
->
mode
&
SPI_3WIRE
)
&&
(
xfer
->
tx_nbits
!=
SPI_NBITS_SINGLE
))
return
-
EINVAL
;
}
/* check transfer rx_nbits */
if
(
xfer
->
rx_buf
)
{
if
(
xfer
->
rx_nbits
!=
SPI_NBITS_SINGLE
&&
xfer
->
rx_nbits
!=
SPI_NBITS_DUAL
&&
xfer
->
rx_nbits
!=
SPI_NBITS_QUAD
)
return
-
EINVAL
;
if
((
xfer
->
rx_nbits
==
SPI_NBITS_DUAL
)
&&
!
(
spi
->
mode
&
(
SPI_RX_DUAL
|
SPI_RX_QUAD
)))
return
-
EINVAL
;
if
((
xfer
->
rx_nbits
==
SPI_NBITS_QUAD
)
&&
!
(
spi
->
mode
&
SPI_RX_QUAD
))
return
-
EINVAL
;
if
((
spi
->
mode
&
SPI_3WIRE
)
&&
(
xfer
->
rx_nbits
!=
SPI_NBITS_SINGLE
))
return
-
EINVAL
;
}
}
message
->
spi
=
spi
;
...
...
include/linux/spi/spi.h
浏览文件 @
21e34a33
...
...
@@ -74,7 +74,7 @@ struct spi_device {
struct
spi_master
*
master
;
u32
max_speed_hz
;
u8
chip_select
;
u
8
mode
;
u
16
mode
;
#define SPI_CPHA 0x01
/* clock phase */
#define SPI_CPOL 0x02
/* clock polarity */
#define SPI_MODE_0 (0|0)
/* (original MicroWire) */
...
...
@@ -87,6 +87,10 @@ struct spi_device {
#define SPI_LOOP 0x20
/* loopback mode */
#define SPI_NO_CS 0x40
/* 1 dev/bus, no chipselect */
#define SPI_READY 0x80
/* slave pulls low to pause */
#define SPI_TX_DUAL 0x100
/* transmit with 2 wires */
#define SPI_TX_QUAD 0x200
/* transmit with 4 wires */
#define SPI_RX_DUAL 0x400
/* receive with 2 wires */
#define SPI_RX_QUAD 0x800
/* receive with 4 wires */
u8
bits_per_word
;
int
irq
;
void
*
controller_state
;
...
...
@@ -233,6 +237,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* suported. If set, the SPI core will reject any transfer with an
* unsupported bits_per_word. If not set, this value is simply ignored,
* and it's up to the individual driver to perform any validation.
* @min_speed_hz: Lowest supported transfer speed
* @max_speed_hz: Highest supported transfer speed
* @flags: other constraints relevant to this driver
* @bus_lock_spinlock: spinlock for SPI bus locking
* @bus_lock_mutex: mutex for SPI bus locking
...
...
@@ -315,6 +321,10 @@ struct spi_master {
#define SPI_BIT_MASK(bits) (((bits) == 32) ? ~0UL : (BIT(bits) - 1))
#define SPI_BPW_RANGE_MASK(min, max) (SPI_BIT_MASK(max) - SPI_BIT_MASK(min - 1))
/* limits on transfer speed */
u32
min_speed_hz
;
u32
max_speed_hz
;
/* other constraints relevant to this driver */
u16
flags
;
#define SPI_MASTER_HALF_DUPLEX BIT(0)
/* can't do full duplex */
...
...
@@ -453,6 +463,10 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
* @rx_buf: data to be read (dma-safe memory), or NULL
* @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped
* @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped
* @tx_nbits: number of bits used for writting. If 0 the default
* (SPI_NBITS_SINGLE) is used.
* @rx_nbits: number of bits used for reading. If 0 the default
* (SPI_NBITS_SINGLE) is used.
* @len: size of rx and tx buffers (in bytes)
* @speed_hz: Select a speed other than the device default for this
* transfer. If 0 the default (from @spi_device) is used.
...
...
@@ -507,6 +521,11 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
* by the results of previous messages and where the whole transaction
* ends when the chipselect goes intactive.
*
* When SPI can transfer in 1x,2x or 4x. It can get this tranfer information
* from device through @tx_nbits and @rx_nbits. In Bi-direction, these
* two should both be set. User can set transfer mode with SPI_NBITS_SINGLE(1x)
* SPI_NBITS_DUAL(2x) and SPI_NBITS_QUAD(4x) to support these three transfer.
*
* The code that submits an spi_message (and its spi_transfers)
* to the lower layers is responsible for managing its memory.
* Zero-initialize every field you don't set up explicitly, to
...
...
@@ -527,6 +546,11 @@ struct spi_transfer {
dma_addr_t
rx_dma
;
unsigned
cs_change
:
1
;
u8
tx_nbits
;
u8
rx_nbits
;
#define SPI_NBITS_SINGLE 0x01
/* 1bit transfer */
#define SPI_NBITS_DUAL 0x02
/* 2bits transfer */
#define SPI_NBITS_QUAD 0x04
/* 4bits transfer */
u8
bits_per_word
;
u16
delay_usecs
;
u32
speed_hz
;
...
...
@@ -874,7 +898,7 @@ struct spi_board_info {
/* mode becomes spi_device.mode, and is essential for chips
* where the default of SPI_CS_HIGH = 0 is wrong.
*/
u
8
mode
;
u
16
mode
;
/* ... may need additional spi_device chip config data here.
* avoid stuff protocol drivers can set; but include stuff
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录