2007-07-17 15:04:11 +04:00
/*
* Xilinx SPI controller driver ( master mode only )
*
* Author : MontaVista Software , Inc .
* source @ mvista . com
*
2010-10-14 19:04:29 +04:00
* Copyright ( c ) 2010 Secret Lab Technologies , Ltd .
* Copyright ( c ) 2009 Intel Corporation
* 2002 - 2007 ( c ) MontaVista Software , 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 .
2007-07-17 15:04:11 +04:00
*/
# include <linux/module.h>
# include <linux/interrupt.h>
2010-10-14 19:32:53 +04:00
# include <linux/of.h>
2010-10-14 19:04:29 +04:00
# include <linux/platform_device.h>
2007-07-17 15:04:11 +04:00
# include <linux/spi/spi.h>
# include <linux/spi/spi_bitbang.h>
2009-11-13 14:28:39 +03:00
# include <linux/spi/xilinx_spi.h>
2010-10-14 19:32:53 +04:00
# include <linux/io.h>
2009-11-13 14:28:39 +03:00
2015-01-28 22:53:39 +03:00
# define XILINX_SPI_MAX_CS 32
2007-08-31 10:56:24 +04:00
# define XILINX_SPI_NAME "xilinx_spi"
2007-07-17 15:04:11 +04:00
/* Register definitions as per "OPB Serial Peripheral Interface (SPI) (v1.00e)
* Product Specification " , DS464
*/
2009-11-13 14:28:55 +03:00
# define XSPI_CR_OFFSET 0x60 /* Control Register */
2007-07-17 15:04:11 +04:00
2013-06-04 18:02:36 +04:00
# define XSPI_CR_LOOP 0x01
2007-07-17 15:04:11 +04:00
# define XSPI_CR_ENABLE 0x02
# define XSPI_CR_MASTER_MODE 0x04
# define XSPI_CR_CPOL 0x08
# define XSPI_CR_CPHA 0x10
2015-01-23 19:08:33 +03:00
# define XSPI_CR_MODE_MASK (XSPI_CR_CPHA | XSPI_CR_CPOL | \
2015-01-23 19:08:34 +03:00
XSPI_CR_LSB_FIRST | XSPI_CR_LOOP )
2007-07-17 15:04:11 +04:00
# define XSPI_CR_TXFIFO_RESET 0x20
# define XSPI_CR_RXFIFO_RESET 0x40
# define XSPI_CR_MANUAL_SSELECT 0x80
# define XSPI_CR_TRANS_INHIBIT 0x100
2009-11-13 14:28:55 +03:00
# define XSPI_CR_LSB_FIRST 0x200
2007-07-17 15:04:11 +04:00
2009-11-13 14:28:55 +03:00
# define XSPI_SR_OFFSET 0x64 /* Status Register */
2007-07-17 15:04:11 +04:00
# define XSPI_SR_RX_EMPTY_MASK 0x01 /* Receive FIFO is empty */
# define XSPI_SR_RX_FULL_MASK 0x02 /* Receive FIFO is full */
# define XSPI_SR_TX_EMPTY_MASK 0x04 /* Transmit FIFO is empty */
# define XSPI_SR_TX_FULL_MASK 0x08 /* Transmit FIFO is full */
# define XSPI_SR_MODE_FAULT_MASK 0x10 /* Mode fault error */
2009-11-13 14:28:55 +03:00
# define XSPI_TXD_OFFSET 0x68 /* Data Transmit Register */
# define XSPI_RXD_OFFSET 0x6c /* Data Receive Register */
2007-07-17 15:04:11 +04:00
# define XSPI_SSR_OFFSET 0x70 /* 32-bit Slave Select Register */
/* Register definitions as per "OPB IPIF (v3.01c) Product Specification", DS414
* IPIF registers are 32 bit
*/
# define XIPIF_V123B_DGIER_OFFSET 0x1c /* IPIF global int enable reg */
# define XIPIF_V123B_GINTR_ENABLE 0x80000000
# define XIPIF_V123B_IISR_OFFSET 0x20 /* IPIF interrupt status reg */
# define XIPIF_V123B_IIER_OFFSET 0x28 /* IPIF interrupt enable reg */
# define XSPI_INTR_MODE_FAULT 0x01 /* Mode fault error */
# define XSPI_INTR_SLAVE_MODE_FAULT 0x02 / * Selected as slave while
* disabled */
# define XSPI_INTR_TX_EMPTY 0x04 /* TxFIFO is empty */
# define XSPI_INTR_TX_UNDERRUN 0x08 /* TxFIFO was underrun */
# define XSPI_INTR_RX_FULL 0x10 /* RxFIFO is full */
# define XSPI_INTR_RX_OVERRUN 0x20 /* RxFIFO was overrun */
2009-11-13 14:28:55 +03:00
# define XSPI_INTR_TX_HALF_EMPTY 0x40 /* TxFIFO is half empty */
2007-07-17 15:04:11 +04:00
# define XIPIF_V123B_RESETR_OFFSET 0x40 /* IPIF reset register */
# define XIPIF_V123B_RESET_MASK 0x0a /* the value to write */
struct xilinx_spi {
/* bitbang has to be first */
struct spi_bitbang bitbang ;
struct completion done ;
void __iomem * regs ; /* virt. address of the control registers */
2013-07-17 19:34:48 +04:00
int irq ;
2007-07-17 15:04:11 +04:00
u8 * rx_ptr ; /* pointer in the Tx buffer */
const u8 * tx_ptr ; /* pointer in the Rx buffer */
2015-01-28 15:23:50 +03:00
u8 bytes_per_word ;
2015-01-28 15:23:40 +03:00
int buffer_size ; /* buffer size in words */
2015-01-28 15:23:46 +03:00
u32 cs_inactive ; /* Level of the CS pins when inactive*/
2014-02-26 05:24:47 +04:00
unsigned int ( * read_fn ) ( void __iomem * ) ;
void ( * write_fn ) ( u32 , void __iomem * ) ;
2007-07-17 15:04:11 +04:00
} ;
2015-01-30 15:42:00 +03:00
static void xspi_write32 ( u32 val , void __iomem * addr )
{
iowrite32 ( val , addr ) ;
}
static unsigned int xspi_read32 ( void __iomem * addr )
{
return ioread32 ( addr ) ;
}
static void xspi_write32_be ( u32 val , void __iomem * addr )
{
iowrite32be ( val , addr ) ;
}
static unsigned int xspi_read32_be ( void __iomem * addr )
{
return ioread32be ( addr ) ;
}
2015-01-28 15:23:47 +03:00
static void xilinx_spi_tx ( struct xilinx_spi * xspi )
2009-11-13 14:28:55 +03:00
{
2015-02-02 13:06:56 +03:00
u32 data = 0 ;
2015-01-28 15:23:48 +03:00
if ( ! xspi - > tx_ptr ) {
xspi - > write_fn ( 0 , xspi - > regs + XSPI_TXD_OFFSET ) ;
return ;
}
2015-02-02 13:06:56 +03:00
switch ( xspi - > bytes_per_word ) {
case 1 :
data = * ( u8 * ) ( xspi - > tx_ptr ) ;
break ;
case 2 :
data = * ( u16 * ) ( xspi - > tx_ptr ) ;
break ;
case 4 :
data = * ( u32 * ) ( xspi - > tx_ptr ) ;
break ;
}
xspi - > write_fn ( data , xspi - > regs + XSPI_TXD_OFFSET ) ;
2015-01-28 15:23:50 +03:00
xspi - > tx_ptr + = xspi - > bytes_per_word ;
2009-11-13 14:28:55 +03:00
}
2015-01-28 15:23:47 +03:00
static void xilinx_spi_rx ( struct xilinx_spi * xspi )
2009-11-13 14:28:55 +03:00
{
u32 data = xspi - > read_fn ( xspi - > regs + XSPI_RXD_OFFSET ) ;
2015-01-28 15:23:47 +03:00
if ( ! xspi - > rx_ptr )
return ;
2009-11-13 14:28:55 +03:00
2015-01-28 15:23:50 +03:00
switch ( xspi - > bytes_per_word ) {
case 1 :
2015-01-28 15:23:47 +03:00
* ( u8 * ) ( xspi - > rx_ptr ) = data ;
break ;
2015-01-28 15:23:50 +03:00
case 2 :
2015-01-28 15:23:47 +03:00
* ( u16 * ) ( xspi - > rx_ptr ) = data ;
break ;
2015-01-28 15:23:50 +03:00
case 4 :
2009-11-13 14:28:55 +03:00
* ( u32 * ) ( xspi - > rx_ptr ) = data ;
2015-01-28 15:23:47 +03:00
break ;
2009-11-13 14:28:55 +03:00
}
2015-01-28 15:23:47 +03:00
2015-01-28 15:23:50 +03:00
xspi - > rx_ptr + = xspi - > bytes_per_word ;
2009-11-13 14:28:55 +03:00
}
2009-11-13 14:28:49 +03:00
static void xspi_init_hw ( struct xilinx_spi * xspi )
2007-07-17 15:04:11 +04:00
{
2009-11-13 14:28:49 +03:00
void __iomem * regs_base = xspi - > regs ;
2007-07-17 15:04:11 +04:00
/* Reset the SPI device */
2009-11-13 14:28:49 +03:00
xspi - > write_fn ( XIPIF_V123B_RESET_MASK ,
regs_base + XIPIF_V123B_RESETR_OFFSET ) ;
2015-01-28 15:23:41 +03:00
/* Enable the transmit empty interrupt, which we use to determine
* progress on the transmission .
*/
xspi - > write_fn ( XSPI_INTR_TX_EMPTY ,
regs_base + XIPIF_V123B_IIER_OFFSET ) ;
2015-01-28 15:23:54 +03:00
/* Disable the global IPIF interrupt */
xspi - > write_fn ( 0 , regs_base + XIPIF_V123B_DGIER_OFFSET ) ;
2007-07-17 15:04:11 +04:00
/* Deselect the slave on the SPI bus */
2009-11-13 14:28:49 +03:00
xspi - > write_fn ( 0xffff , regs_base + XSPI_SSR_OFFSET ) ;
2007-07-17 15:04:11 +04:00
/* Disable the transmitter, enable Manual Slave Select Assertion,
* put SPI controller into master mode , and enable it */
2015-01-28 15:23:54 +03:00
xspi - > write_fn ( XSPI_CR_MANUAL_SSELECT | XSPI_CR_MASTER_MODE |
XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET | XSPI_CR_RXFIFO_RESET ,
regs_base + XSPI_CR_OFFSET ) ;
2007-07-17 15:04:11 +04:00
}
static void xilinx_spi_chipselect ( struct spi_device * spi , int is_on )
{
struct xilinx_spi * xspi = spi_master_get_devdata ( spi - > master ) ;
2015-01-28 15:23:46 +03:00
u16 cr ;
u32 cs ;
2007-07-17 15:04:11 +04:00
if ( is_on = = BITBANG_CS_INACTIVE ) {
/* Deselect the slave on the SPI bus */
2015-01-28 15:23:46 +03:00
xspi - > write_fn ( xspi - > cs_inactive , xspi - > regs + XSPI_SSR_OFFSET ) ;
return ;
2007-07-17 15:04:11 +04:00
}
2015-01-28 15:23:46 +03:00
/* Set the SPI clock phase and polarity */
cr = xspi - > read_fn ( xspi - > regs + XSPI_CR_OFFSET ) & ~ XSPI_CR_MODE_MASK ;
if ( spi - > mode & SPI_CPHA )
cr | = XSPI_CR_CPHA ;
if ( spi - > mode & SPI_CPOL )
cr | = XSPI_CR_CPOL ;
if ( spi - > mode & SPI_LSB_FIRST )
cr | = XSPI_CR_LSB_FIRST ;
if ( spi - > mode & SPI_LOOP )
cr | = XSPI_CR_LOOP ;
xspi - > write_fn ( cr , xspi - > regs + XSPI_CR_OFFSET ) ;
/* We do not check spi->max_speed_hz here as the SPI clock
* frequency is not software programmable ( the IP block design
* parameter )
*/
cs = xspi - > cs_inactive ;
cs ^ = BIT ( spi - > chip_select ) ;
/* Activate the chip select */
xspi - > write_fn ( cs , xspi - > regs + XSPI_SSR_OFFSET ) ;
2007-07-17 15:04:11 +04:00
}
/* spi_bitbang requires custom setup_transfer() to be defined if there is a
2014-02-14 17:06:43 +04:00
* custom txrx_bufs ( ) .
2007-07-17 15:04:11 +04:00
*/
static int xilinx_spi_setup_transfer ( struct spi_device * spi ,
struct spi_transfer * t )
{
2015-01-28 15:23:46 +03:00
struct xilinx_spi * xspi = spi_master_get_devdata ( spi - > master ) ;
if ( spi - > mode & SPI_CS_HIGH )
xspi - > cs_inactive & = ~ BIT ( spi - > chip_select ) ;
else
xspi - > cs_inactive | = BIT ( spi - > chip_select ) ;
2007-07-17 15:04:11 +04:00
return 0 ;
}
static int xilinx_spi_txrx_bufs ( struct spi_device * spi , struct spi_transfer * t )
{
struct xilinx_spi * xspi = spi_master_get_devdata ( spi - > master ) ;
2015-01-28 15:23:52 +03:00
int remaining_words ; /* the number of words left to transfer */
2015-01-28 15:23:54 +03:00
bool use_irq = false ;
u16 cr = 0 ;
2007-07-17 15:04:11 +04:00
/* We get here with transmitter inhibited */
xspi - > tx_ptr = t - > tx_buf ;
xspi - > rx_ptr = t - > rx_buf ;
2015-01-28 15:23:52 +03:00
remaining_words = t - > len / xspi - > bytes_per_word ;
2007-07-17 15:04:11 +04:00
2015-01-28 15:23:54 +03:00
if ( xspi - > irq > = 0 & & remaining_words > xspi - > buffer_size ) {
2015-08-13 17:09:28 +03:00
u32 isr ;
2015-01-28 15:23:54 +03:00
use_irq = true ;
/* Inhibit irq to avoid spurious irqs on tx_empty*/
cr = xspi - > read_fn ( xspi - > regs + XSPI_CR_OFFSET ) ;
xspi - > write_fn ( cr | XSPI_CR_TRANS_INHIBIT ,
xspi - > regs + XSPI_CR_OFFSET ) ;
2015-08-13 17:09:28 +03:00
/* ACK old irqs (if any) */
isr = xspi - > read_fn ( xspi - > regs + XIPIF_V123B_IISR_OFFSET ) ;
if ( isr )
xspi - > write_fn ( isr ,
xspi - > regs + XIPIF_V123B_IISR_OFFSET ) ;
/* Enable the global IPIF interrupt */
xspi - > write_fn ( XIPIF_V123B_GINTR_ENABLE ,
xspi - > regs + XIPIF_V123B_DGIER_OFFSET ) ;
reinit_completion ( & xspi - > done ) ;
2015-01-28 15:23:54 +03:00
}
2015-01-28 15:23:52 +03:00
while ( remaining_words ) {
int n_words , tx_words , rx_words ;
2015-10-28 18:16:02 +03:00
u32 sr ;
2017-11-21 12:09:02 +03:00
int stalled ;
2013-06-04 18:02:34 +04:00
2015-01-28 15:23:52 +03:00
n_words = min ( remaining_words , xspi - > buffer_size ) ;
2015-01-28 15:23:40 +03:00
2015-01-28 15:23:52 +03:00
tx_words = n_words ;
while ( tx_words - - )
xilinx_spi_tx ( xspi ) ;
2013-06-04 18:02:34 +04:00
/* Start the transfer by not inhibiting the transmitter any
* longer
*/
2015-01-28 15:23:54 +03:00
if ( use_irq ) {
2015-01-28 15:23:45 +03:00
xspi - > write_fn ( cr , xspi - > regs + XSPI_CR_OFFSET ) ;
2015-01-28 15:23:44 +03:00
wait_for_completion ( & xspi - > done ) ;
2015-10-28 18:16:02 +03:00
/* A transmit has just completed. Process received data
* and check for more data to transmit . Always inhibit
* the transmitter while the Isr refills the transmit
* register / FIFO , or make sure it is stopped if we ' re
* done .
*/
2015-01-28 15:23:45 +03:00
xspi - > write_fn ( cr | XSPI_CR_TRANS_INHIBIT ,
2015-10-28 18:16:02 +03:00
xspi - > regs + XSPI_CR_OFFSET ) ;
sr = XSPI_SR_TX_EMPTY_MASK ;
} else
sr = xspi - > read_fn ( xspi - > regs + XSPI_SR_OFFSET ) ;
2013-06-04 18:02:34 +04:00
/* Read out all the data from the Rx FIFO */
2015-01-28 15:23:52 +03:00
rx_words = n_words ;
2017-11-21 12:09:02 +03:00
stalled = 10 ;
2015-10-28 18:16:02 +03:00
while ( rx_words ) {
2017-11-21 12:09:02 +03:00
if ( rx_words = = n_words & & ! ( stalled - - ) & &
! ( sr & XSPI_SR_TX_EMPTY_MASK ) & &
( sr & XSPI_SR_RX_EMPTY_MASK ) ) {
dev_err ( & spi - > dev ,
" Detected stall. Check C_SPI_MODE and C_SPI_MEMORY \n " ) ;
xspi_init_hw ( xspi ) ;
return - EIO ;
}
2015-10-28 18:16:02 +03:00
if ( ( sr & XSPI_SR_TX_EMPTY_MASK ) & & ( rx_words > 1 ) ) {
xilinx_spi_rx ( xspi ) ;
rx_words - - ;
continue ;
}
sr = xspi - > read_fn ( xspi - > regs + XSPI_SR_OFFSET ) ;
if ( ! ( sr & XSPI_SR_RX_EMPTY_MASK ) ) {
xilinx_spi_rx ( xspi ) ;
rx_words - - ;
}
}
2015-01-28 15:23:52 +03:00
remaining_words - = n_words ;
2013-06-04 18:02:34 +04:00
}
2007-07-17 15:04:11 +04:00
2015-08-12 19:04:04 +03:00
if ( use_irq ) {
2015-01-28 15:23:54 +03:00
xspi - > write_fn ( 0 , xspi - > regs + XIPIF_V123B_DGIER_OFFSET ) ;
2015-08-12 19:04:04 +03:00
xspi - > write_fn ( cr , xspi - > regs + XSPI_CR_OFFSET ) ;
}
2015-01-28 15:23:54 +03:00
2015-01-28 15:23:49 +03:00
return t - > len ;
2007-07-17 15:04:11 +04:00
}
/* This driver supports single master mode only. Hence Tx FIFO Empty
* is the only interrupt we care about .
* Receive FIFO Overrun , Transmit FIFO Underrun , Mode Fault , and Slave Mode
* Fault are not to happen .
*/
static irqreturn_t xilinx_spi_irq ( int irq , void * dev_id )
{
struct xilinx_spi * xspi = dev_id ;
u32 ipif_isr ;
/* Get the IPIF interrupts, and clear them immediately */
2009-11-13 14:28:49 +03:00
ipif_isr = xspi - > read_fn ( xspi - > regs + XIPIF_V123B_IISR_OFFSET ) ;
xspi - > write_fn ( ipif_isr , xspi - > regs + XIPIF_V123B_IISR_OFFSET ) ;
2007-07-17 15:04:11 +04:00
if ( ipif_isr & XSPI_INTR_TX_EMPTY ) { /* Transmission completed */
2013-06-04 18:02:34 +04:00
complete ( & xspi - > done ) ;
2016-07-15 12:04:19 +03:00
return IRQ_HANDLED ;
2007-07-17 15:04:11 +04:00
}
2016-07-15 12:04:19 +03:00
return IRQ_NONE ;
2007-07-17 15:04:11 +04:00
}
2015-01-28 15:23:40 +03:00
static int xilinx_spi_find_buffer_size ( struct xilinx_spi * xspi )
{
u8 sr ;
int n_words = 0 ;
/*
* Before the buffer_size detection we reset the core
* to make sure we start with a clean state .
*/
xspi - > write_fn ( XIPIF_V123B_RESET_MASK ,
xspi - > regs + XIPIF_V123B_RESETR_OFFSET ) ;
/* Fill the Tx FIFO with as many words as possible */
do {
xspi - > write_fn ( 0 , xspi - > regs + XSPI_TXD_OFFSET ) ;
sr = xspi - > read_fn ( xspi - > regs + XSPI_SR_OFFSET ) ;
n_words + + ;
} while ( ! ( sr & XSPI_SR_TX_FULL_MASK ) ) ;
return n_words ;
}
2010-10-14 19:32:53 +04:00
static const struct of_device_id xilinx_spi_of_match [ ] = {
2017-11-21 12:09:03 +03:00
{ . compatible = " xlnx,axi-quad-spi-1.00.a " , } ,
2010-10-14 19:32:53 +04:00
{ . compatible = " xlnx,xps-spi-2.00.a " , } ,
{ . compatible = " xlnx,xps-spi-2.00.b " , } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , xilinx_spi_of_match ) ;
2013-07-05 14:24:26 +04:00
static int xilinx_spi_probe ( struct platform_device * pdev )
2007-07-17 15:04:11 +04:00
{
struct xilinx_spi * xspi ;
2013-07-03 15:05:42 +04:00
struct xspi_platform_data * pdata ;
2013-07-08 17:29:15 +04:00
struct resource * res ;
2013-07-09 20:05:16 +04:00
int ret , num_cs = 0 , bits_per_word = 8 ;
2013-07-03 15:05:42 +04:00
struct spi_master * master ;
2013-06-04 18:02:36 +04:00
u32 tmp ;
2013-07-03 15:05:42 +04:00
u8 i ;
2013-07-30 11:58:59 +04:00
pdata = dev_get_platdata ( & pdev - > dev ) ;
2013-07-03 15:05:42 +04:00
if ( pdata ) {
num_cs = pdata - > num_chipselect ;
bits_per_word = pdata - > bits_per_word ;
2013-07-08 17:29:17 +04:00
} else {
of_property_read_u32 ( pdev - > dev . of_node , " xlnx,num-ss-bits " ,
& num_cs ) ;
2013-07-03 15:05:42 +04:00
}
2007-07-17 15:04:11 +04:00
2013-07-03 15:05:42 +04:00
if ( ! num_cs ) {
2013-07-05 14:24:26 +04:00
dev_err ( & pdev - > dev ,
" Missing slave select configuration data \n " ) ;
2013-07-03 15:05:42 +04:00
return - EINVAL ;
}
2015-01-28 22:53:39 +03:00
if ( num_cs > XILINX_SPI_MAX_CS ) {
dev_err ( & pdev - > dev , " Invalid number of spi slaves \n " ) ;
return - EINVAL ;
}
2013-07-05 14:24:26 +04:00
master = spi_alloc_master ( & pdev - > dev , sizeof ( struct xilinx_spi ) ) ;
2009-11-13 14:28:39 +03:00
if ( ! master )
2013-07-03 15:05:42 +04:00
return - ENODEV ;
2007-07-17 15:04:11 +04:00
2009-06-18 03:26:04 +04:00
/* the spi->mode bits understood by this driver: */
2015-01-28 15:23:46 +03:00
master - > mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP |
SPI_CS_HIGH ;
2009-06-18 03:26:04 +04:00
2007-07-17 15:04:11 +04:00
xspi = spi_master_get_devdata ( master ) ;
2015-01-28 15:23:46 +03:00
xspi - > cs_inactive = 0xffffffff ;
2013-09-10 11:43:41 +04:00
xspi - > bitbang . master = master ;
2007-07-17 15:04:11 +04:00
xspi - > bitbang . chipselect = xilinx_spi_chipselect ;
xspi - > bitbang . setup_transfer = xilinx_spi_setup_transfer ;
xspi - > bitbang . txrx_bufs = xilinx_spi_txrx_bufs ;
init_completion ( & xspi - > done ) ;
2013-07-08 17:29:15 +04:00
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
xspi - > regs = devm_ioremap_resource ( & pdev - > dev , res ) ;
2013-07-01 23:33:01 +04:00
if ( IS_ERR ( xspi - > regs ) ) {
ret = PTR_ERR ( xspi - > regs ) ;
2007-07-17 15:04:11 +04:00
goto put_master ;
}
2014-07-10 12:30:20 +04:00
master - > bus_num = pdev - > id ;
2010-10-14 18:54:55 +04:00
master - > num_chipselect = num_cs ;
2013-07-05 14:24:26 +04:00
master - > dev . of_node = pdev - > dev . of_node ;
2013-06-04 18:02:36 +04:00
/*
* Detect endianess on the IP via loop bit in CR . Detection
* must be done before reset is sent because incorrect reset
* value generates error interrupt .
* Setup little endian helper functions first and try to use them
* and check if bit was correctly setup or not .
*/
2015-01-30 15:42:00 +03:00
xspi - > read_fn = xspi_read32 ;
xspi - > write_fn = xspi_write32 ;
2013-06-04 18:02:36 +04:00
xspi - > write_fn ( XSPI_CR_LOOP , xspi - > regs + XSPI_CR_OFFSET ) ;
tmp = xspi - > read_fn ( xspi - > regs + XSPI_CR_OFFSET ) ;
tmp & = XSPI_CR_LOOP ;
if ( tmp ! = XSPI_CR_LOOP ) {
2015-01-30 15:42:00 +03:00
xspi - > read_fn = xspi_read32_be ;
xspi - > write_fn = xspi_write32_be ;
2009-11-13 14:28:49 +03:00
}
2013-06-04 18:02:36 +04:00
2014-02-14 17:06:43 +04:00
master - > bits_per_word_mask = SPI_BPW_MASK ( bits_per_word ) ;
2015-01-28 15:23:50 +03:00
xspi - > bytes_per_word = bits_per_word / 8 ;
2015-01-28 15:23:40 +03:00
xspi - > buffer_size = xilinx_spi_find_buffer_size ( xspi ) ;
2013-07-09 20:05:16 +04:00
xspi - > irq = platform_get_irq ( pdev , 0 ) ;
2016-07-15 12:04:18 +03:00
if ( xspi - > irq < 0 & & xspi - > irq ! = - ENXIO ) {
ret = xspi - > irq ;
goto put_master ;
} else if ( xspi - > irq > = 0 ) {
2015-01-28 15:23:44 +03:00
/* Register for SPI Interrupt */
ret = devm_request_irq ( & pdev - > dev , xspi - > irq , xilinx_spi_irq , 0 ,
dev_name ( & pdev - > dev ) , xspi ) ;
if ( ret )
goto put_master ;
2013-07-09 20:05:16 +04:00
}
2015-01-28 15:23:44 +03:00
/* SPI controller initializations */
xspi_init_hw ( xspi ) ;
2007-07-17 15:04:11 +04:00
2009-11-13 14:28:39 +03:00
ret = spi_bitbang_start ( & xspi - > bitbang ) ;
if ( ret ) {
2013-07-05 14:24:26 +04:00
dev_err ( & pdev - > dev , " spi_bitbang_start FAILED \n " ) ;
2013-07-09 20:05:16 +04:00
goto put_master ;
2010-10-14 19:32:53 +04:00
}
2013-07-05 14:24:26 +04:00
dev_info ( & pdev - > dev , " at 0x%08llX mapped to 0x%p, irq=%d \n " ,
2013-07-08 17:29:15 +04:00
( unsigned long long ) res - > start , xspi - > regs , xspi - > irq ) ;
2010-10-14 19:04:29 +04:00
2010-10-14 19:32:53 +04:00
if ( pdata ) {
for ( i = 0 ; i < pdata - > num_devices ; i + + )
spi_new_device ( master , pdata - > devices + i ) ;
}
2010-10-14 19:04:29 +04:00
2013-07-05 14:24:26 +04:00
platform_set_drvdata ( pdev , master ) ;
2010-10-14 19:04:29 +04:00
return 0 ;
2007-07-17 15:04:11 +04:00
put_master :
spi_master_put ( master ) ;
2013-07-03 15:05:42 +04:00
return ret ;
2010-10-14 19:04:29 +04:00
}
2013-07-05 14:24:26 +04:00
static int xilinx_spi_remove ( struct platform_device * pdev )
2010-10-14 19:04:29 +04:00
{
2013-07-05 14:24:26 +04:00
struct spi_master * master = platform_get_drvdata ( pdev ) ;
2013-07-03 15:05:42 +04:00
struct xilinx_spi * xspi = spi_master_get_devdata ( master ) ;
2013-07-09 20:05:16 +04:00
void __iomem * regs_base = xspi - > regs ;
2007-07-17 15:04:11 +04:00
spi_bitbang_stop ( & xspi - > bitbang ) ;
2013-07-09 20:05:16 +04:00
/* Disable all the interrupts just in case */
xspi - > write_fn ( 0 , regs_base + XIPIF_V123B_IIER_OFFSET ) ;
/* Disable the global IPIF interrupt */
xspi - > write_fn ( 0 , regs_base + XIPIF_V123B_DGIER_OFFSET ) ;
2009-01-10 02:01:53 +03:00
2009-11-13 14:28:39 +03:00
spi_master_put ( xspi - > bitbang . master ) ;
2010-10-14 19:04:29 +04:00
return 0 ;
}
/* work with hotplug and coldplug */
MODULE_ALIAS ( " platform: " XILINX_SPI_NAME ) ;
static struct platform_driver xilinx_spi_driver = {
. probe = xilinx_spi_probe ,
2012-12-07 20:57:14 +04:00
. remove = xilinx_spi_remove ,
2010-10-14 19:04:29 +04:00
. driver = {
. name = XILINX_SPI_NAME ,
2010-10-14 19:32:53 +04:00
. of_match_table = xilinx_spi_of_match ,
2010-10-14 19:04:29 +04:00
} ,
} ;
2011-10-05 21:29:49 +04:00
module_platform_driver ( xilinx_spi_driver ) ;
2010-10-14 19:04:29 +04:00
2007-07-17 15:04:11 +04:00
MODULE_AUTHOR ( " MontaVista Software, Inc. <source@mvista.com> " ) ;
MODULE_DESCRIPTION ( " Xilinx SPI driver " ) ;
MODULE_LICENSE ( " GPL " ) ;