mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
docs: networking: convert caif files to ReST
There are two text files for caif, plus one already converted file. Convert the two remaining ones to ReST, create a new index.rst file for CAIF, adding it to the main networking documentation index. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
790ab249b5
commit
da50d57abd
@@ -1,5 +1,3 @@
|
|||||||
:orphan:
|
|
||||||
|
|
||||||
.. SPDX-License-Identifier: GPL-2.0
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
.. include:: <isonum.txt>
|
.. include:: <isonum.txt>
|
||||||
|
|
||||||
|
13
Documentation/networking/caif/index.rst
Normal file
13
Documentation/networking/caif/index.rst
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
CAIF
|
||||||
|
====
|
||||||
|
|
||||||
|
Contents:
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
linux_caif
|
||||||
|
caif
|
||||||
|
spi_porting
|
@@ -1,12 +1,19 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
.. include:: <isonum.txt>
|
||||||
|
|
||||||
|
==========
|
||||||
Linux CAIF
|
Linux CAIF
|
||||||
===========
|
==========
|
||||||
copyright (C) ST-Ericsson AB 2010
|
|
||||||
Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
|
Copyright |copy| ST-Ericsson AB 2010
|
||||||
License terms: GNU General Public License (GPL) version 2
|
|
||||||
|
:Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
|
||||||
|
:License terms: GNU General Public License (GPL) version 2
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
============
|
||||||
|
|
||||||
CAIF is a MUX protocol used by ST-Ericsson cellular modems for
|
CAIF is a MUX protocol used by ST-Ericsson cellular modems for
|
||||||
communication between Modem and host. The host processes can open virtual AT
|
communication between Modem and host. The host processes can open virtual AT
|
||||||
channels, initiate GPRS Data connections, Video channels and Utility Channels.
|
channels, initiate GPRS Data connections, Video channels and Utility Channels.
|
||||||
@@ -16,13 +23,16 @@ ST-Ericsson modems support a number of transports between modem
|
|||||||
and host. Currently, UART and Loopback are available for Linux.
|
and host. Currently, UART and Loopback are available for Linux.
|
||||||
|
|
||||||
|
|
||||||
Architecture:
|
Architecture
|
||||||
------------
|
============
|
||||||
|
|
||||||
The implementation of CAIF is divided into:
|
The implementation of CAIF is divided into:
|
||||||
|
|
||||||
* CAIF Socket Layer and GPRS IP Interface.
|
* CAIF Socket Layer and GPRS IP Interface.
|
||||||
* CAIF Core Protocol Implementation
|
* CAIF Core Protocol Implementation
|
||||||
* CAIF Link Layer, implemented as NET devices.
|
* CAIF Link Layer, implemented as NET devices.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
RTNL
|
RTNL
|
||||||
!
|
!
|
||||||
@@ -46,12 +56,12 @@ The implementation of CAIF is divided into:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
I M P L E M E N T A T I O N
|
Implementation
|
||||||
===========================
|
==============
|
||||||
|
|
||||||
|
|
||||||
CAIF Core Protocol Layer
|
CAIF Core Protocol Layer
|
||||||
=========================================
|
------------------------
|
||||||
|
|
||||||
CAIF Core layer implements the CAIF protocol as defined by ST-Ericsson.
|
CAIF Core layer implements the CAIF protocol as defined by ST-Ericsson.
|
||||||
It implements the CAIF protocol stack in a layered approach, where
|
It implements the CAIF protocol stack in a layered approach, where
|
||||||
@@ -59,8 +69,11 @@ each layer described in the specification is implemented as a separate layer.
|
|||||||
The architecture is inspired by the design patterns "Protocol Layer" and
|
The architecture is inspired by the design patterns "Protocol Layer" and
|
||||||
"Protocol Packet".
|
"Protocol Packet".
|
||||||
|
|
||||||
== CAIF structure ==
|
CAIF structure
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The Core CAIF implementation contains:
|
The Core CAIF implementation contains:
|
||||||
|
|
||||||
- Simple implementation of CAIF.
|
- Simple implementation of CAIF.
|
||||||
- Layered architecture (a la Streams), each layer in the CAIF
|
- Layered architecture (a la Streams), each layer in the CAIF
|
||||||
specification is implemented in a separate c-file.
|
specification is implemented in a separate c-file.
|
||||||
@@ -73,7 +86,8 @@ The Core CAIF implementation contains:
|
|||||||
to the called function (except for framing layers' receive function)
|
to the called function (except for framing layers' receive function)
|
||||||
|
|
||||||
Layered Architecture
|
Layered Architecture
|
||||||
--------------------
|
====================
|
||||||
|
|
||||||
The CAIF protocol can be divided into two parts: Support functions and Protocol
|
The CAIF protocol can be divided into two parts: Support functions and Protocol
|
||||||
Implementation. The support functions include:
|
Implementation. The support functions include:
|
||||||
|
|
||||||
@@ -112,7 +126,7 @@ The CAIF Protocol implementation contains:
|
|||||||
- CFSERL CAIF Serial layer. Handles concatenation/split of frames
|
- CFSERL CAIF Serial layer. Handles concatenation/split of frames
|
||||||
into CAIF Frames with correct length.
|
into CAIF Frames with correct length.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
+---------+
|
+---------+
|
||||||
| Config |
|
| Config |
|
||||||
@@ -143,18 +157,24 @@ The CAIF Protocol implementation contains:
|
|||||||
|
|
||||||
|
|
||||||
In this layered approach the following "rules" apply.
|
In this layered approach the following "rules" apply.
|
||||||
|
|
||||||
- All layers embed the same structure "struct cflayer"
|
- All layers embed the same structure "struct cflayer"
|
||||||
- A layer does not depend on any other layer's private data.
|
- A layer does not depend on any other layer's private data.
|
||||||
- Layers are stacked by setting the pointers
|
- Layers are stacked by setting the pointers::
|
||||||
|
|
||||||
layer->up , layer->dn
|
layer->up , layer->dn
|
||||||
- In order to send data upwards, each layer should do
|
|
||||||
|
- In order to send data upwards, each layer should do::
|
||||||
|
|
||||||
layer->up->receive(layer->up, packet);
|
layer->up->receive(layer->up, packet);
|
||||||
- In order to send data downwards, each layer should do
|
|
||||||
|
- In order to send data downwards, each layer should do::
|
||||||
|
|
||||||
layer->dn->transmit(layer->dn, packet);
|
layer->dn->transmit(layer->dn, packet);
|
||||||
|
|
||||||
|
|
||||||
CAIF Socket and IP interface
|
CAIF Socket and IP interface
|
||||||
===========================
|
============================
|
||||||
|
|
||||||
The IP interface and CAIF socket API are implemented on top of the
|
The IP interface and CAIF socket API are implemented on top of the
|
||||||
CAIF Core protocol. The IP Interface and CAIF socket have an instance of
|
CAIF Core protocol. The IP Interface and CAIF socket have an instance of
|
229
Documentation/networking/caif/spi_porting.rst
Normal file
229
Documentation/networking/caif/spi_porting.rst
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
================
|
||||||
|
CAIF SPI porting
|
||||||
|
================
|
||||||
|
|
||||||
|
CAIF SPI basics
|
||||||
|
===============
|
||||||
|
|
||||||
|
Running CAIF over SPI needs some extra setup, owing to the nature of SPI.
|
||||||
|
Two extra GPIOs have been added in order to negotiate the transfers
|
||||||
|
between the master and the slave. The minimum requirement for running
|
||||||
|
CAIF over SPI is a SPI slave chip and two GPIOs (more details below).
|
||||||
|
Please note that running as a slave implies that you need to keep up
|
||||||
|
with the master clock. An overrun or underrun event is fatal.
|
||||||
|
|
||||||
|
CAIF SPI framework
|
||||||
|
==================
|
||||||
|
|
||||||
|
To make porting as easy as possible, the CAIF SPI has been divided in
|
||||||
|
two parts. The first part (called the interface part) deals with all
|
||||||
|
generic functionality such as length framing, SPI frame negotiation
|
||||||
|
and SPI frame delivery and transmission. The other part is the CAIF
|
||||||
|
SPI slave device part, which is the module that you have to write if
|
||||||
|
you want to run SPI CAIF on a new hardware. This part takes care of
|
||||||
|
the physical hardware, both with regard to SPI and to GPIOs.
|
||||||
|
|
||||||
|
- Implementing a CAIF SPI device:
|
||||||
|
|
||||||
|
- Functionality provided by the CAIF SPI slave device:
|
||||||
|
|
||||||
|
In order to implement a SPI device you will, as a minimum,
|
||||||
|
need to implement the following
|
||||||
|
functions:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
int (*init_xfer) (struct cfspi_xfer * xfer, struct cfspi_dev *dev):
|
||||||
|
|
||||||
|
This function is called by the CAIF SPI interface to give
|
||||||
|
you a chance to set up your hardware to be ready to receive
|
||||||
|
a stream of data from the master. The xfer structure contains
|
||||||
|
both physical and logical addresses, as well as the total length
|
||||||
|
of the transfer in both directions.The dev parameter can be used
|
||||||
|
to map to different CAIF SPI slave devices.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
void (*sig_xfer) (bool xfer, struct cfspi_dev *dev):
|
||||||
|
|
||||||
|
This function is called by the CAIF SPI interface when the output
|
||||||
|
(SPI_INT) GPIO needs to change state. The boolean value of the xfer
|
||||||
|
variable indicates whether the GPIO should be asserted (HIGH) or
|
||||||
|
deasserted (LOW). The dev parameter can be used to map to different CAIF
|
||||||
|
SPI slave devices.
|
||||||
|
|
||||||
|
- Functionality provided by the CAIF SPI interface:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
void (*ss_cb) (bool assert, struct cfspi_ifc *ifc);
|
||||||
|
|
||||||
|
This function is called by the CAIF SPI slave device in order to
|
||||||
|
signal a change of state of the input GPIO (SS) to the interface.
|
||||||
|
Only active edges are mandatory to be reported.
|
||||||
|
This function can be called from IRQ context (recommended in order
|
||||||
|
not to introduce latency). The ifc parameter should be the pointer
|
||||||
|
returned from the platform probe function in the SPI device structure.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
void (*xfer_done_cb) (struct cfspi_ifc *ifc);
|
||||||
|
|
||||||
|
This function is called by the CAIF SPI slave device in order to
|
||||||
|
report that a transfer is completed. This function should only be
|
||||||
|
called once both the transmission and the reception are completed.
|
||||||
|
This function can be called from IRQ context (recommended in order
|
||||||
|
not to introduce latency). The ifc parameter should be the pointer
|
||||||
|
returned from the platform probe function in the SPI device structure.
|
||||||
|
|
||||||
|
- Connecting the bits and pieces:
|
||||||
|
|
||||||
|
- Filling in the SPI slave device structure:
|
||||||
|
|
||||||
|
Connect the necessary callback functions.
|
||||||
|
|
||||||
|
Indicate clock speed (used to calculate toggle delays).
|
||||||
|
|
||||||
|
Chose a suitable name (helps debugging if you use several CAIF
|
||||||
|
SPI slave devices).
|
||||||
|
|
||||||
|
Assign your private data (can be used to map to your
|
||||||
|
structure).
|
||||||
|
|
||||||
|
- Filling in the SPI slave platform device structure:
|
||||||
|
|
||||||
|
Add name of driver to connect to ("cfspi_sspi").
|
||||||
|
|
||||||
|
Assign the SPI slave device structure as platform data.
|
||||||
|
|
||||||
|
Padding
|
||||||
|
=======
|
||||||
|
|
||||||
|
In order to optimize throughput, a number of SPI padding options are provided.
|
||||||
|
Padding can be enabled independently for uplink and downlink transfers.
|
||||||
|
Padding can be enabled for the head, the tail and for the total frame size.
|
||||||
|
The padding needs to be correctly configured on both sides of the link.
|
||||||
|
The padding can be changed via module parameters in cfspi_sspi.c or via
|
||||||
|
the sysfs directory of the cfspi_sspi driver (before device registration).
|
||||||
|
|
||||||
|
- CAIF SPI device template::
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) ST-Ericsson AB 2010
|
||||||
|
* Author: Daniel Martensson / Daniel.Martensson@stericsson.com
|
||||||
|
* License terms: GNU General Public License (GPL), version 2.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/wait.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
#include <net/caif/caif_spi.h>
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
struct sspi_struct {
|
||||||
|
struct cfspi_dev sdev;
|
||||||
|
struct cfspi_xfer *xfer;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sspi_struct slave;
|
||||||
|
static struct platform_device slave_device;
|
||||||
|
|
||||||
|
static irqreturn_t sspi_irq(int irq, void *arg)
|
||||||
|
{
|
||||||
|
/* You only need to trigger on an edge to the active state of the
|
||||||
|
* SS signal. Once a edge is detected, the ss_cb() function should be
|
||||||
|
* called with the parameter assert set to true. It is OK
|
||||||
|
* (and even advised) to call the ss_cb() function in IRQ context in
|
||||||
|
* order not to add any delay. */
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sspi_complete(void *context)
|
||||||
|
{
|
||||||
|
/* Normally the DMA or the SPI framework will call you back
|
||||||
|
* in something similar to this. The only thing you need to
|
||||||
|
* do is to call the xfer_done_cb() function, providing the pointer
|
||||||
|
* to the CAIF SPI interface. It is OK to call this function
|
||||||
|
* from IRQ context. */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sspi_init_xfer(struct cfspi_xfer *xfer, struct cfspi_dev *dev)
|
||||||
|
{
|
||||||
|
/* Store transfer info. For a normal implementation you should
|
||||||
|
* set up your DMA here and make sure that you are ready to
|
||||||
|
* receive the data from the master SPI. */
|
||||||
|
|
||||||
|
struct sspi_struct *sspi = (struct sspi_struct *)dev->priv;
|
||||||
|
|
||||||
|
sspi->xfer = xfer;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sspi_sig_xfer(bool xfer, struct cfspi_dev *dev)
|
||||||
|
{
|
||||||
|
/* If xfer is true then you should assert the SPI_INT to indicate to
|
||||||
|
* the master that you are ready to receive the data from the master
|
||||||
|
* SPI. If xfer is false then you should de-assert SPI_INT to indicate
|
||||||
|
* that the transfer is done.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct sspi_struct *sspi = (struct sspi_struct *)dev->priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sspi_release(struct device *dev)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Here you should release your SPI device resources.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init sspi_init(void)
|
||||||
|
{
|
||||||
|
/* Here you should initialize your SPI device by providing the
|
||||||
|
* necessary functions, clock speed, name and private data. Once
|
||||||
|
* done, you can register your device with the
|
||||||
|
* platform_device_register() function. This function will return
|
||||||
|
* with the CAIF SPI interface initialized. This is probably also
|
||||||
|
* the place where you should set up your GPIOs, interrupts and SPI
|
||||||
|
* resources. */
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
/* Initialize slave device. */
|
||||||
|
slave.sdev.init_xfer = sspi_init_xfer;
|
||||||
|
slave.sdev.sig_xfer = sspi_sig_xfer;
|
||||||
|
slave.sdev.clk_mhz = 13;
|
||||||
|
slave.sdev.priv = &slave;
|
||||||
|
slave.sdev.name = "spi_sspi";
|
||||||
|
slave_device.dev.release = sspi_release;
|
||||||
|
|
||||||
|
/* Initialize platform device. */
|
||||||
|
slave_device.name = "cfspi_sspi";
|
||||||
|
slave_device.dev.platform_data = &slave.sdev;
|
||||||
|
|
||||||
|
/* Register platform device. */
|
||||||
|
res = platform_device_register(&slave_device);
|
||||||
|
if (res) {
|
||||||
|
printk(KERN_WARNING "sspi_init: failed to register dev.\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit sspi_exit(void)
|
||||||
|
{
|
||||||
|
platform_device_del(&slave_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(sspi_init);
|
||||||
|
module_exit(sspi_exit);
|
@@ -1,208 +0,0 @@
|
|||||||
- CAIF SPI porting -
|
|
||||||
|
|
||||||
- CAIF SPI basics:
|
|
||||||
|
|
||||||
Running CAIF over SPI needs some extra setup, owing to the nature of SPI.
|
|
||||||
Two extra GPIOs have been added in order to negotiate the transfers
|
|
||||||
between the master and the slave. The minimum requirement for running
|
|
||||||
CAIF over SPI is a SPI slave chip and two GPIOs (more details below).
|
|
||||||
Please note that running as a slave implies that you need to keep up
|
|
||||||
with the master clock. An overrun or underrun event is fatal.
|
|
||||||
|
|
||||||
- CAIF SPI framework:
|
|
||||||
|
|
||||||
To make porting as easy as possible, the CAIF SPI has been divided in
|
|
||||||
two parts. The first part (called the interface part) deals with all
|
|
||||||
generic functionality such as length framing, SPI frame negotiation
|
|
||||||
and SPI frame delivery and transmission. The other part is the CAIF
|
|
||||||
SPI slave device part, which is the module that you have to write if
|
|
||||||
you want to run SPI CAIF on a new hardware. This part takes care of
|
|
||||||
the physical hardware, both with regard to SPI and to GPIOs.
|
|
||||||
|
|
||||||
- Implementing a CAIF SPI device:
|
|
||||||
|
|
||||||
- Functionality provided by the CAIF SPI slave device:
|
|
||||||
|
|
||||||
In order to implement a SPI device you will, as a minimum,
|
|
||||||
need to implement the following
|
|
||||||
functions:
|
|
||||||
|
|
||||||
int (*init_xfer) (struct cfspi_xfer * xfer, struct cfspi_dev *dev):
|
|
||||||
|
|
||||||
This function is called by the CAIF SPI interface to give
|
|
||||||
you a chance to set up your hardware to be ready to receive
|
|
||||||
a stream of data from the master. The xfer structure contains
|
|
||||||
both physical and logical addresses, as well as the total length
|
|
||||||
of the transfer in both directions.The dev parameter can be used
|
|
||||||
to map to different CAIF SPI slave devices.
|
|
||||||
|
|
||||||
void (*sig_xfer) (bool xfer, struct cfspi_dev *dev):
|
|
||||||
|
|
||||||
This function is called by the CAIF SPI interface when the output
|
|
||||||
(SPI_INT) GPIO needs to change state. The boolean value of the xfer
|
|
||||||
variable indicates whether the GPIO should be asserted (HIGH) or
|
|
||||||
deasserted (LOW). The dev parameter can be used to map to different CAIF
|
|
||||||
SPI slave devices.
|
|
||||||
|
|
||||||
- Functionality provided by the CAIF SPI interface:
|
|
||||||
|
|
||||||
void (*ss_cb) (bool assert, struct cfspi_ifc *ifc);
|
|
||||||
|
|
||||||
This function is called by the CAIF SPI slave device in order to
|
|
||||||
signal a change of state of the input GPIO (SS) to the interface.
|
|
||||||
Only active edges are mandatory to be reported.
|
|
||||||
This function can be called from IRQ context (recommended in order
|
|
||||||
not to introduce latency). The ifc parameter should be the pointer
|
|
||||||
returned from the platform probe function in the SPI device structure.
|
|
||||||
|
|
||||||
void (*xfer_done_cb) (struct cfspi_ifc *ifc);
|
|
||||||
|
|
||||||
This function is called by the CAIF SPI slave device in order to
|
|
||||||
report that a transfer is completed. This function should only be
|
|
||||||
called once both the transmission and the reception are completed.
|
|
||||||
This function can be called from IRQ context (recommended in order
|
|
||||||
not to introduce latency). The ifc parameter should be the pointer
|
|
||||||
returned from the platform probe function in the SPI device structure.
|
|
||||||
|
|
||||||
- Connecting the bits and pieces:
|
|
||||||
|
|
||||||
- Filling in the SPI slave device structure:
|
|
||||||
|
|
||||||
Connect the necessary callback functions.
|
|
||||||
Indicate clock speed (used to calculate toggle delays).
|
|
||||||
Chose a suitable name (helps debugging if you use several CAIF
|
|
||||||
SPI slave devices).
|
|
||||||
Assign your private data (can be used to map to your structure).
|
|
||||||
|
|
||||||
- Filling in the SPI slave platform device structure:
|
|
||||||
Add name of driver to connect to ("cfspi_sspi").
|
|
||||||
Assign the SPI slave device structure as platform data.
|
|
||||||
|
|
||||||
- Padding:
|
|
||||||
|
|
||||||
In order to optimize throughput, a number of SPI padding options are provided.
|
|
||||||
Padding can be enabled independently for uplink and downlink transfers.
|
|
||||||
Padding can be enabled for the head, the tail and for the total frame size.
|
|
||||||
The padding needs to be correctly configured on both sides of the link.
|
|
||||||
The padding can be changed via module parameters in cfspi_sspi.c or via
|
|
||||||
the sysfs directory of the cfspi_sspi driver (before device registration).
|
|
||||||
|
|
||||||
- CAIF SPI device template:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) ST-Ericsson AB 2010
|
|
||||||
* Author: Daniel Martensson / Daniel.Martensson@stericsson.com
|
|
||||||
* License terms: GNU General Public License (GPL), version 2.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/wait.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/dma-mapping.h>
|
|
||||||
#include <net/caif/caif_spi.h>
|
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
||||||
struct sspi_struct {
|
|
||||||
struct cfspi_dev sdev;
|
|
||||||
struct cfspi_xfer *xfer;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct sspi_struct slave;
|
|
||||||
static struct platform_device slave_device;
|
|
||||||
|
|
||||||
static irqreturn_t sspi_irq(int irq, void *arg)
|
|
||||||
{
|
|
||||||
/* You only need to trigger on an edge to the active state of the
|
|
||||||
* SS signal. Once a edge is detected, the ss_cb() function should be
|
|
||||||
* called with the parameter assert set to true. It is OK
|
|
||||||
* (and even advised) to call the ss_cb() function in IRQ context in
|
|
||||||
* order not to add any delay. */
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sspi_complete(void *context)
|
|
||||||
{
|
|
||||||
/* Normally the DMA or the SPI framework will call you back
|
|
||||||
* in something similar to this. The only thing you need to
|
|
||||||
* do is to call the xfer_done_cb() function, providing the pointer
|
|
||||||
* to the CAIF SPI interface. It is OK to call this function
|
|
||||||
* from IRQ context. */
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sspi_init_xfer(struct cfspi_xfer *xfer, struct cfspi_dev *dev)
|
|
||||||
{
|
|
||||||
/* Store transfer info. For a normal implementation you should
|
|
||||||
* set up your DMA here and make sure that you are ready to
|
|
||||||
* receive the data from the master SPI. */
|
|
||||||
|
|
||||||
struct sspi_struct *sspi = (struct sspi_struct *)dev->priv;
|
|
||||||
|
|
||||||
sspi->xfer = xfer;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sspi_sig_xfer(bool xfer, struct cfspi_dev *dev)
|
|
||||||
{
|
|
||||||
/* If xfer is true then you should assert the SPI_INT to indicate to
|
|
||||||
* the master that you are ready to receive the data from the master
|
|
||||||
* SPI. If xfer is false then you should de-assert SPI_INT to indicate
|
|
||||||
* that the transfer is done.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct sspi_struct *sspi = (struct sspi_struct *)dev->priv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sspi_release(struct device *dev)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Here you should release your SPI device resources.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init sspi_init(void)
|
|
||||||
{
|
|
||||||
/* Here you should initialize your SPI device by providing the
|
|
||||||
* necessary functions, clock speed, name and private data. Once
|
|
||||||
* done, you can register your device with the
|
|
||||||
* platform_device_register() function. This function will return
|
|
||||||
* with the CAIF SPI interface initialized. This is probably also
|
|
||||||
* the place where you should set up your GPIOs, interrupts and SPI
|
|
||||||
* resources. */
|
|
||||||
|
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
/* Initialize slave device. */
|
|
||||||
slave.sdev.init_xfer = sspi_init_xfer;
|
|
||||||
slave.sdev.sig_xfer = sspi_sig_xfer;
|
|
||||||
slave.sdev.clk_mhz = 13;
|
|
||||||
slave.sdev.priv = &slave;
|
|
||||||
slave.sdev.name = "spi_sspi";
|
|
||||||
slave_device.dev.release = sspi_release;
|
|
||||||
|
|
||||||
/* Initialize platform device. */
|
|
||||||
slave_device.name = "cfspi_sspi";
|
|
||||||
slave_device.dev.platform_data = &slave.sdev;
|
|
||||||
|
|
||||||
/* Register platform device. */
|
|
||||||
res = platform_device_register(&slave_device);
|
|
||||||
if (res) {
|
|
||||||
printk(KERN_WARNING "sspi_init: failed to register dev.\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit sspi_exit(void)
|
|
||||||
{
|
|
||||||
platform_device_del(&slave_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(sspi_init);
|
|
||||||
module_exit(sspi_exit);
|
|
@@ -15,6 +15,7 @@ Contents:
|
|||||||
device_drivers/index
|
device_drivers/index
|
||||||
dsa/index
|
dsa/index
|
||||||
devlink/index
|
devlink/index
|
||||||
|
caif/index
|
||||||
ethtool-netlink
|
ethtool-netlink
|
||||||
ieee802154
|
ieee802154
|
||||||
j1939
|
j1939
|
||||||
|
@@ -28,7 +28,7 @@ config CAIF_SPI_SLAVE
|
|||||||
The CAIF Link layer SPI Protocol driver for Slave SPI interface.
|
The CAIF Link layer SPI Protocol driver for Slave SPI interface.
|
||||||
This driver implements a platform driver to accommodate for a
|
This driver implements a platform driver to accommodate for a
|
||||||
platform specific SPI device. A sample CAIF SPI Platform device is
|
platform specific SPI device. A sample CAIF SPI Platform device is
|
||||||
provided in <file:Documentation/networking/caif/spi_porting.txt>.
|
provided in <file:Documentation/networking/caif/spi_porting.rst>.
|
||||||
|
|
||||||
config CAIF_SPI_SYNC
|
config CAIF_SPI_SYNC
|
||||||
bool "Next command and length in start of frame"
|
bool "Next command and length in start of frame"
|
||||||
|
Reference in New Issue
Block a user