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
nexedi
linux
Commits
3c103974
Commit
3c103974
authored
Jan 23, 2014
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'spi/topic/core' into spi-linus
parents
7e2c225d
1afd9989
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
34 additions
and
28 deletions
+34
-28
Documentation/spi/spi-summary
Documentation/spi/spi-summary
+4
-4
drivers/spi/spi.c
drivers/spi/spi.c
+26
-20
include/linux/spi/spi.h
include/linux/spi/spi.h
+4
-4
No files found.
Documentation/spi/spi-summary
View file @
3c103974
...
@@ -34,7 +34,7 @@ SPI slave functions are usually not interoperable between vendors
...
@@ -34,7 +34,7 @@ SPI slave functions are usually not interoperable between vendors
- It may also be used to stream data in either direction (half duplex),
- It may also be used to stream data in either direction (half duplex),
or both of them at the same time (full duplex).
or both of them at the same time (full duplex).
- Some devices may use eight bit words. Others may different word
- Some devices may use eight bit words. Others may
use
different word
lengths, such as streams of 12-bit or 20-bit digital samples.
lengths, such as streams of 12-bit or 20-bit digital samples.
- Words are usually sent with their most significant bit (MSB) first,
- Words are usually sent with their most significant bit (MSB) first,
...
@@ -121,7 +121,7 @@ active. So the master must set the clock to inactive before selecting
...
@@ -121,7 +121,7 @@ active. So the master must set the clock to inactive before selecting
a slave, and the slave can tell the chosen polarity by sampling the
a slave, and the slave can tell the chosen polarity by sampling the
clock level when its select line goes active. That's why many devices
clock level when its select line goes active. That's why many devices
support for example both modes 0 and 3: they don't care about polarity,
support for example both modes 0 and 3: they don't care about polarity,
and alway clock data in/out on rising clock edges.
and alway
s
clock data in/out on rising clock edges.
How do these driver programming interfaces work?
How do these driver programming interfaces work?
...
@@ -139,7 +139,7 @@ a command and then reading its response.
...
@@ -139,7 +139,7 @@ a command and then reading its response.
There are two types of SPI driver, here called:
There are two types of SPI driver, here called:
Controller drivers ... controllers may be built in
to System-On-Chip
Controller drivers ... controllers may be built into System-On-Chip
processors, and often support both Master and Slave roles.
processors, and often support both Master and Slave roles.
These drivers touch hardware registers and may use DMA.
These drivers touch hardware registers and may use DMA.
Or they can be PIO bitbangers, needing just GPIO pins.
Or they can be PIO bitbangers, needing just GPIO pins.
...
@@ -548,7 +548,7 @@ SPI MASTER METHODS
...
@@ -548,7 +548,7 @@ SPI MASTER METHODS
DEPRECATED METHODS
DEPRECATED METHODS
master->transfer(struct spi_device *spi, struct spi_message *message)
master->transfer(struct spi_device *spi, struct spi_message *message)
This must not sleep. Its responsibility is arrange that the
This must not sleep. Its responsibility is
to
arrange that the
transfer happens and its complete() callback is issued. The two
transfer happens and its complete() callback is issued. The two
will normally happen later, after other transfers complete, and
will normally happen later, after other transfers complete, and
if the controller is idle it will need to be kickstarted. This
if the controller is idle it will need to be kickstarted. This
...
...
drivers/spi/spi.c
View file @
3c103974
...
@@ -695,7 +695,7 @@ static void spi_pump_messages(struct kthread_work *work)
...
@@ -695,7 +695,7 @@ static void spi_pump_messages(struct kthread_work *work)
}
}
/* Extract head of queue */
/* Extract head of queue */
master
->
cur_msg
=
master
->
cur_msg
=
list_entry
(
master
->
queue
.
next
,
struct
spi_message
,
queue
);
list_first_entry
(
&
master
->
queue
,
struct
spi_message
,
queue
);
list_del_init
(
&
master
->
cur_msg
->
queue
);
list_del_init
(
&
master
->
cur_msg
->
queue
);
if
(
master
->
busy
)
if
(
master
->
busy
)
...
@@ -803,11 +803,8 @@ struct spi_message *spi_get_next_queued_message(struct spi_master *master)
...
@@ -803,11 +803,8 @@ struct spi_message *spi_get_next_queued_message(struct spi_master *master)
/* get a pointer to the next message, if any */
/* get a pointer to the next message, if any */
spin_lock_irqsave
(
&
master
->
queue_lock
,
flags
);
spin_lock_irqsave
(
&
master
->
queue_lock
,
flags
);
if
(
list_empty
(
&
master
->
queue
))
next
=
list_first_entry_or_null
(
&
master
->
queue
,
struct
spi_message
,
next
=
NULL
;
queue
);
else
next
=
list_entry
(
master
->
queue
.
next
,
struct
spi_message
,
queue
);
spin_unlock_irqrestore
(
&
master
->
queue_lock
,
flags
);
spin_unlock_irqrestore
(
&
master
->
queue_lock
,
flags
);
return
next
;
return
next
;
...
@@ -1608,15 +1605,11 @@ int spi_setup(struct spi_device *spi)
...
@@ -1608,15 +1605,11 @@ int spi_setup(struct spi_device *spi)
}
}
EXPORT_SYMBOL_GPL
(
spi_setup
);
EXPORT_SYMBOL_GPL
(
spi_setup
);
static
int
__spi_
async
(
struct
spi_device
*
spi
,
struct
spi_message
*
message
)
static
int
__spi_
validate
(
struct
spi_device
*
spi
,
struct
spi_message
*
message
)
{
{
struct
spi_master
*
master
=
spi
->
master
;
struct
spi_master
*
master
=
spi
->
master
;
struct
spi_transfer
*
xfer
;
struct
spi_transfer
*
xfer
;
message
->
spi
=
spi
;
trace_spi_message_submit
(
message
);
if
(
list_empty
(
&
message
->
transfers
))
if
(
list_empty
(
&
message
->
transfers
))
return
-
EINVAL
;
return
-
EINVAL
;
if
(
!
message
->
complete
)
if
(
!
message
->
complete
)
...
@@ -1679,9 +1672,8 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
...
@@ -1679,9 +1672,8 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
if
(
xfer
->
rx_buf
&&
!
xfer
->
rx_nbits
)
if
(
xfer
->
rx_buf
&&
!
xfer
->
rx_nbits
)
xfer
->
rx_nbits
=
SPI_NBITS_SINGLE
;
xfer
->
rx_nbits
=
SPI_NBITS_SINGLE
;
/* check transfer tx/rx_nbits:
/* check transfer tx/rx_nbits:
* 1. keep the value is not out of single, dual and quad
* 1. check the value matches one of single, dual and quad
* 2. keep tx/rx_nbits is contained by mode in spi_device
* 2. check tx/rx_nbits match the mode in spi_device
* 3. if SPI_3WIRE, tx/rx_nbits should be in single
*/
*/
if
(
xfer
->
tx_buf
)
{
if
(
xfer
->
tx_buf
)
{
if
(
xfer
->
tx_nbits
!=
SPI_NBITS_SINGLE
&&
if
(
xfer
->
tx_nbits
!=
SPI_NBITS_SINGLE
&&
...
@@ -1694,9 +1686,6 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
...
@@ -1694,9 +1686,6 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
if
((
xfer
->
tx_nbits
==
SPI_NBITS_QUAD
)
&&
if
((
xfer
->
tx_nbits
==
SPI_NBITS_QUAD
)
&&
!
(
spi
->
mode
&
SPI_TX_QUAD
))
!
(
spi
->
mode
&
SPI_TX_QUAD
))
return
-
EINVAL
;
return
-
EINVAL
;
if
((
spi
->
mode
&
SPI_3WIRE
)
&&
(
xfer
->
tx_nbits
!=
SPI_NBITS_SINGLE
))
return
-
EINVAL
;
}
}
/* check transfer rx_nbits */
/* check transfer rx_nbits */
if
(
xfer
->
rx_buf
)
{
if
(
xfer
->
rx_buf
)
{
...
@@ -1710,13 +1699,22 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
...
@@ -1710,13 +1699,22 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
if
((
xfer
->
rx_nbits
==
SPI_NBITS_QUAD
)
&&
if
((
xfer
->
rx_nbits
==
SPI_NBITS_QUAD
)
&&
!
(
spi
->
mode
&
SPI_RX_QUAD
))
!
(
spi
->
mode
&
SPI_RX_QUAD
))
return
-
EINVAL
;
return
-
EINVAL
;
if
((
spi
->
mode
&
SPI_3WIRE
)
&&
(
xfer
->
rx_nbits
!=
SPI_NBITS_SINGLE
))
return
-
EINVAL
;
}
}
}
}
message
->
status
=
-
EINPROGRESS
;
message
->
status
=
-
EINPROGRESS
;
return
0
;
}
static
int
__spi_async
(
struct
spi_device
*
spi
,
struct
spi_message
*
message
)
{
struct
spi_master
*
master
=
spi
->
master
;
message
->
spi
=
spi
;
trace_spi_message_submit
(
message
);
return
master
->
transfer
(
spi
,
message
);
return
master
->
transfer
(
spi
,
message
);
}
}
...
@@ -1755,6 +1753,10 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
...
@@ -1755,6 +1753,10 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
int
ret
;
int
ret
;
unsigned
long
flags
;
unsigned
long
flags
;
ret
=
__spi_validate
(
spi
,
message
);
if
(
ret
!=
0
)
return
ret
;
spin_lock_irqsave
(
&
master
->
bus_lock_spinlock
,
flags
);
spin_lock_irqsave
(
&
master
->
bus_lock_spinlock
,
flags
);
if
(
master
->
bus_lock_flag
)
if
(
master
->
bus_lock_flag
)
...
@@ -1803,6 +1805,10 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message)
...
@@ -1803,6 +1805,10 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message)
int
ret
;
int
ret
;
unsigned
long
flags
;
unsigned
long
flags
;
ret
=
__spi_validate
(
spi
,
message
);
if
(
ret
!=
0
)
return
ret
;
spin_lock_irqsave
(
&
master
->
bus_lock_spinlock
,
flags
);
spin_lock_irqsave
(
&
master
->
bus_lock_spinlock
,
flags
);
ret
=
__spi_async
(
spi
,
message
);
ret
=
__spi_async
(
spi
,
message
);
...
...
include/linux/spi/spi.h
View file @
3c103974
...
@@ -75,6 +75,7 @@ struct spi_device {
...
@@ -75,6 +75,7 @@ struct spi_device {
struct
spi_master
*
master
;
struct
spi_master
*
master
;
u32
max_speed_hz
;
u32
max_speed_hz
;
u8
chip_select
;
u8
chip_select
;
u8
bits_per_word
;
u16
mode
;
u16
mode
;
#define SPI_CPHA 0x01
/* clock phase */
#define SPI_CPHA 0x01
/* clock phase */
#define SPI_CPOL 0x02
/* clock polarity */
#define SPI_CPOL 0x02
/* clock polarity */
...
@@ -92,7 +93,6 @@ struct spi_device {
...
@@ -92,7 +93,6 @@ struct spi_device {
#define SPI_TX_QUAD 0x200
/* transmit with 4 wires */
#define SPI_TX_QUAD 0x200
/* transmit with 4 wires */
#define SPI_RX_DUAL 0x400
/* receive with 2 wires */
#define SPI_RX_DUAL 0x400
/* receive with 2 wires */
#define SPI_RX_QUAD 0x800
/* receive with 4 wires */
#define SPI_RX_QUAD 0x800
/* receive with 4 wires */
u8
bits_per_word
;
int
irq
;
int
irq
;
void
*
controller_state
;
void
*
controller_state
;
void
*
controller_data
;
void
*
controller_data
;
...
@@ -578,8 +578,8 @@ struct spi_transfer {
...
@@ -578,8 +578,8 @@ struct spi_transfer {
dma_addr_t
rx_dma
;
dma_addr_t
rx_dma
;
unsigned
cs_change
:
1
;
unsigned
cs_change
:
1
;
u
8
tx_nbits
;
u
nsigned
tx_nbits
:
3
;
u
8
rx_nbits
;
u
nsigned
rx_nbits
:
3
;
#define SPI_NBITS_SINGLE 0x01
/* 1bit transfer */
#define SPI_NBITS_SINGLE 0x01
/* 1bit transfer */
#define SPI_NBITS_DUAL 0x02
/* 2bits transfer */
#define SPI_NBITS_DUAL 0x02
/* 2bits transfer */
#define SPI_NBITS_QUAD 0x04
/* 4bits transfer */
#define SPI_NBITS_QUAD 0x04
/* 4bits transfer */
...
@@ -849,7 +849,7 @@ static inline ssize_t spi_w8r16(struct spi_device *spi, u8 cmd)
...
@@ -849,7 +849,7 @@ static inline ssize_t spi_w8r16(struct spi_device *spi, u8 cmd)
ssize_t
status
;
ssize_t
status
;
u16
result
;
u16
result
;
status
=
spi_write_then_read
(
spi
,
&
cmd
,
1
,
(
u8
*
)
&
result
,
2
);
status
=
spi_write_then_read
(
spi
,
&
cmd
,
1
,
&
result
,
2
);
/* return negative errno or unsigned value */
/* return negative errno or unsigned value */
return
(
status
<
0
)
?
status
:
result
;
return
(
status
<
0
)
?
status
:
result
;
...
...
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