/*
* A driver for the ARM PL022 PrimeCell SSP/SPI bus master.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/spi/spi.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl022.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <linux/pm_runtime.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
/*
* This macro is used to define some register default values.
* reg is masked with mask, the OR:ed with an (again masked)
* val shifted sb steps to the left.
*/
#define SSP_WRITE_BITS(reg, val, mask, sb) \
((reg) = (((reg) & ~(mask)) | (((val)<<(sb)) & (mask))))
/*
* This macro is also used to define some default values.
* It will just shift val by sb steps to the left and mask
* the result with mask.
*/
#define GEN_MASK_BITS(val, mask, sb) \
(((val)<<(sb)) & (mask))
#define DRIVE_TX 0
#define DO_NOT_DRIVE_TX 1
#define DO_NOT_QUEUE_DMA 0
#define QUEUE_DMA 1
#define RX_TRANSFER 1
#define TX_TRANSFER 2
/*
* Macros to access SSP Registers with their offsets
*/
#define SSP_CR0(r) (r + 0x000)
#define SSP_CR1(r) (r + 0x004)
#define SSP_DR(r) (r + 0x008)
#define SSP_SR(r) (r + 0x00C)
#define SSP_CPSR(r) (r + 0x010)
#define SSP_IMSC(r) (r + 0x014)
#define SSP_RIS(r) (r + 0x018)
#define SSP_MIS(r) (r + 0x01C)
#define SSP_ICR(r) (r + 0x020)
#define SSP_DMACR(r) (r + 0x024)
#define SSP_ITCR(r) (r + 0x080)
#define SSP_ITIP(r) (r + 0x084)
#define SSP_ITOP(r) (r + 0x088)
#define SSP_TDR(r) (r + 0x08C)
#define SSP_PID0(r) (r + 0xFE0)
#define SSP_PID1(r) (r + 0xFE4)
#define SSP_PID2(r) (r + 0xFE8)
#define SSP_PID3(r) (r + 0xFEC)
#define SSP_CID0(r) (r + 0xFF0)
#define SSP_CID1(r) (r + 0xFF4)
#define SSP_CID2(r) (r + 0xFF8)
#define SSP_CID3(r) (r + 0xFFC)
/*
* SSP Control Register 0 - SSP_CR0
*/
#define SSP_CR0_MASK_DSS (0x0FUL << 0)
#define SSP_CR0_MASK_FRF (0x3UL << 4)
#define SSP_CR0_MASK_SPO (0x1UL << 6)
#define SSP_CR0_MASK_SPH (0x1UL << 7)
#define SSP_CR0_MASK_SCR (0xFFUL << 8)
/*
* The ST version of this block moves som bits
* in SSP_CR0 and extends it to 32 bits
*/
#define SSP_CR0_MASK_DSS_ST (0x1FUL << 0)
#define SSP_CR0_MASK_HALFDUP_ST (0x1UL << 5)
#define SSP_CR0_MASK_CSS_ST (0x1FUL << 16)
#define SSP_CR0_MASK_FRF_ST (0x3UL << 21)
/*
* SSP Control Register 0 - SSP_CR1
*/
#define SSP_CR1_MASK_LBM (0x1UL << 0)
#define SSP_CR1_MASK_SSE (0x1UL << 1)
#define SSP_CR1_MASK_MS (0x1UL << 2)
#define SSP_CR1_MASK_SOD (0x1UL << 3)
/*
* The ST version of this block adds some bits
* in SSP_CR1
*/
#define SSP_CR1_MASK_RENDN_ST (0x1UL << 4)
#define SSP_CR1_MASK_TENDN_ST (0x1UL << 5)
#define SSP_CR1_MASK_MWAIT_ST (0x1UL << 6)
#define SSP_CR1_MASK_RXIFLSEL_ST (0x7UL << 7)
#define SSP_CR1_MASK_TXIFLSEL_ST (0x7UL << 10)
/* This one is only in the PL023 variant */
#define SSP_CR1_MASK_FBCLKDEL_ST (0x7UL << 13)
/*
* SSP Status Register - SSP_SR
*/
#define SSP_SR_MASK_TFE (0x1UL << 0) /* Transmit FIFO empty */
#define SSP_SR_MASK_TNF (0x1UL << 1) /* Transmit FIFO not full */
#define SSP_SR_MASK_RNE (0x1UL << 2) /* Receive FIFO not empty */
#define SSP_SR_MASK_RFF (0x1UL << 3) /* Receive FIFO full */
#define SSP_SR_MASK_BSY (0x1UL << 4) /* Busy Flag */
/*
* SSP Clock Prescale Register - SSP_CPSR
*/
#define SSP_CPSR_MASK_CPSDVSR (0xFFUL << 0)
/*
* SSP Interrupt Mask Set/Clear Register - SSP_IMSC
*/
#define SSP_IMSC_MASK_RORIM (0x1UL << 0) /* Receive Overrun Interrupt mask */
#define SSP_IMSC_MASK_RTIM (0x1UL << 1) /* Receive timeout Interrupt mask */
#define SSP_IMSC_MASK_RXIM (0x1UL << 2) /* Receive FIFO Interrupt mask */
#define SSP_IMSC_MASK_TXIM (0x1UL << 3) /* Transmit FIFO Interrupt mask */
/*
* SSP Raw Interrupt Status Register - SSP_RIS
*/
/* Receive Overrun Raw Interrupt status */
#define SSP_RIS_MASK_RORRIS (0x1UL << 0)
/* Receive Timeout Raw Interrupt status */
#define SSP_RIS_MASK_RTRIS (0x1UL << 1)
/* Receive FIFO Raw Interrupt status */
#define SSP_RIS_MASK_RXRIS (0x1UL << 2)
/* Transmit FIFO Raw Interrupt status */
#define SSP_RIS_MASK_TXRIS (0x1UL << 3)
/*
* SSP Masked Interrupt Status Register - SSP_MIS
*/
/* Receive Overrun Masked Interrupt status */
#define SSP_MIS_MASK_RORMIS (0x1UL << 0)
/* Receive Timeout Masked Interrupt status */
#define SSP_MIS_MASK_RTMIS (0x1UL << 1)
/* Receive FIFO Masked Interrupt status */
#define SSP_MIS_MASK_RXMIS (0x1UL << 2)
/* Transmit FIFO Masked Interrupt status */
#define SSP_MIS_MASK_TXMIS (0x1UL << 3)
/*
* SSP Interrupt Clear Register - SSP_ICR
*/
/* Receive Overrun Raw Clear Interrupt bit */
#define SSP_ICR_MASK_RORIC (0x1UL << 0)
/* Receive Timeout Clear Interrupt bit */
#define SSP_ICR_MASK_RTIC (0x1UL << 1)
/*
* SSP DMA Control Register - SSP_DMACR
*/
/* Receive DMA Enable bit */
#define SSP_DMACR_MASK_RXDMAE (0x1UL << 0)
/* Transmit DMA Enable bit */
#define SSP_DMACR_MASK_TXDMAE (0x1UL << 1)
/*
* SSP Integration Test control Register - SSP_ITCR
*/
#define SSP_ITCR_MASK_ITEN (0x1UL << 0)
#define SSP_ITCR_MASK_TESTFIFO (0x1UL << 1)
/*
* SSP Integration Test Input Register - SSP_ITIP
*/
#define ITIP_MASK_SSPRXD (0x1UL << 0)
#define ITIP_MASK_SSPFSSIN (0x1UL << 1)
#define ITIP_MASK_SSPCLKIN (0x1UL << 2)
#define ITIP_MASK_RXDMAC (0x1UL << 3)
#define ITIP_MASK_TXDMAC (0x1UL << 4)
#define ITIP_MASK_SSPTXDIN (0x1UL << 5)
/*
* SSP Integration Test output Register - SSP_ITOP
*/
#define ITOP_MASK_SSPTXD (0x1UL << 0)
#define ITOP_MASK_SSPFSSOUT (0x1UL << 1)
#define ITOP_MASK_SSPCLKOUT (0x1UL << 2)
#define ITOP_MASK_SSPOEn (0x1UL << 3)
#define ITOP_MASK_SSPCTLOEn (0x1UL << 4)
#define ITOP_MASK_RORINTR (0x1UL << 5)
#define ITOP_MASK_RTINTR (0x1UL << 6)
#define ITOP_MASK_RXINTR (0x1UL << 7)
#define ITOP_MASK_TXINTR (0x1UL << 8)
#define ITOP_MASK_INTR (0x1UL << 9)
#define ITOP_MASK_RXDMABREQ (0x1UL << 10)
#define ITOP_MASK_RXDMASREQ (0x1UL << 11)
#define ITOP_MASK_TXDMABREQ (0x1UL << 12)
#define ITOP_MASK_TXDMASREQ (0x1UL << 13)
/*
* SSP Test Data Register - SSP_TDR
*/
#define TDR_MASK_TESTDATA (0xFFFFFFFF)
/*
* Message State
* we use the spi_message.state (void *) pointer to
* hold a single state value, that's why all this
* (void *) casting is done here.
*/
#define STATE_START ((void *) 0)
#define STATE_RUNNING ((void *) 1)
#define STATE_DONE ((void *) 2)
#define STATE_ERROR ((void *) -1)
/*
* SSP State - Whether Enabled or Disabled
*/
#define SSP_DISABLED (0)
#define SSP_ENABLED (1)
/*
* SSP DMA State - Whether DMA Enabled or Disabled
*/
#define SSP_DMA_DISABLED (0)
#define SSP_DMA_ENABLED (1)
/*
* SSP Clock Defaults
*/
#define SSP_DEFAULT_CLKRATE 0x2
#define SSP_DEFAULT_PRESCALE 0x40
/*
* SSP Clock Parameter ranges
*/
#define CPSDVR_MIN 0x02
#define CPSDVR_MAX 0xFE
#define SCR_MIN 0x00
#define SCR_MAX 0xFF
/*
* SSP Interrupt related Macros
*/
#define DEFAULT_SSP_REG_IMSC 0x0UL
#define DISABLE_ALL_INTERRUPTS DEFAULT_SSP_REG_IMSC
#define ENABLE_ALL_INTERRUPTS (~DEFAULT_SSP_REG_IMSC)
#define CLEAR_ALL_INTERRUPTS 0x3
#define SPI_POLLING_TIMEOUT 1000
/*
* The type of reading going on on this chip
*/
enum ssp_reading {
READING_NULL,
READING_U8,
READING_U16,
READING_U32
};
/**
* The type of writing going on on this chip
*/
enum ssp_writing {
WRITING_NULL,
WRITING_U8,
WRITING_U16,
WRITING_U32
};
/**
* struct vendor_data - vendor-specific config parameters
* for PL022 derivates
* @fifodepth: depth of FIFOs (both)
* @max_bpw: maximum number of bits per word
* @unidir: supports unidirection transfers
* @extended_cr: 32 bit wide control register 0 with extra
* features and extra features in CR1 as found in the ST variants
* @pl023: supports a subset of the ST extensions called "PL023"
*/
struct vendor_data {
int fif
spi-pl022.rar_The Bus_arm的pl022_pl022 ssp_primecell_ssp spi
版权申诉
116 浏览量
2022-09-23
16:42:37
上传
评论
收藏 17KB RAR 举报
APei
- 粉丝: 63
- 资源: 1万+
最新资源
- DrawDB 是一个健壮且用户友好的数据库实体关系 (DBER) 编辑器,直接位于您的浏览器中
- PHP库通过返回原始SQL来实现ActiveRecord 用于PHP5.3和NO PDO场景的yii2 ORM移植
- 5152单片机proteus仿真和源码用数组作函数参数控制流水花样
- 2024年全域电商矩阵109节线上课-课程网盘链接提取码下载 .txt
- 对 sqlite 的使用进行简单封装,仅涉及简单的单表 增删改查,基于 FMDB, 操作基于 model
- 5152单片机proteus仿真和源码用函数型指针控制P1口灯花样
- 对Hibernate框架的二次封装,简化对数据库的操作
- 5152单片机proteus仿真和源码用定时器T1查询方式控制单片机发出1KHz音频
- 由 Top10 开发和使用的惯用 Scala Redis 客户端 这是一项正在进行的工作,虽然在生产中使用,但应将其视为在生产中
- SwiftUI - SceanAppDelegate
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈