/*
* Driver for Cirrus Logic EP93xx SPI controller.
*
* Copyright (C) 2010-2011 Mika Westerberg
*
* Explicit FIFO handling code was inspired by amba-pl022 driver.
*
* Chip select support using other than built-in GPIOs by H. Hartley Sweeten.
*
* For more information about the SPI controller see documentation on Cirrus
* Logic web site:
* http://www.cirrus.com/en/pubs/manual/EP93xx_Users_Guide_UM1.pdf
*
* 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.
*/
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dmaengine.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/scatterlist.h>
#include <linux/spi/spi.h>
#include <linux/platform_data/dma-ep93xx.h>
#include <linux/platform_data/spi-ep93xx.h>
#define SSPCR0 0x0000
#define SSPCR0_MODE_SHIFT 6
#define SSPCR0_SCR_SHIFT 8
#define SSPCR1 0x0004
#define SSPCR1_RIE BIT(0)
#define SSPCR1_TIE BIT(1)
#define SSPCR1_RORIE BIT(2)
#define SSPCR1_LBM BIT(3)
#define SSPCR1_SSE BIT(4)
#define SSPCR1_MS BIT(5)
#define SSPCR1_SOD BIT(6)
#define SSPDR 0x0008
#define SSPSR 0x000c
#define SSPSR_TFE BIT(0)
#define SSPSR_TNF BIT(1)
#define SSPSR_RNE BIT(2)
#define SSPSR_RFF BIT(3)
#define SSPSR_BSY BIT(4)
#define SSPCPSR 0x0010
#define SSPIIR 0x0014
#define SSPIIR_RIS BIT(0)
#define SSPIIR_TIS BIT(1)
#define SSPIIR_RORIS BIT(2)
#define SSPICR SSPIIR
/* timeout in milliseconds */
#define SPI_TIMEOUT 5
/* maximum depth of RX/TX FIFO */
#define SPI_FIFO_SIZE 8
/**
* struct ep93xx_spi - EP93xx SPI controller structure
* @lock: spinlock that protects concurrent accesses to fields @running,
* @current_msg and @msg_queue
* @pdev: pointer to platform device
* @clk: clock for the controller
* @regs_base: pointer to ioremap()'d registers
* @sspdr_phys: physical address of the SSPDR register
* @min_rate: minimum clock rate (in Hz) supported by the controller
* @max_rate: maximum clock rate (in Hz) supported by the controller
* @running: is the queue running
* @wq: workqueue used by the driver
* @msg_work: work that is queued for the driver
* @wait: wait here until given transfer is completed
* @msg_queue: queue for the messages
* @current_msg: message that is currently processed (or %NULL if none)
* @tx: current byte in transfer to transmit
* @rx: current byte in transfer to receive
* @fifo_level: how full is FIFO (%0..%SPI_FIFO_SIZE - %1). Receiving one
* frame decreases this level and sending one frame increases it.
* @dma_rx: RX DMA channel
* @dma_tx: TX DMA channel
* @dma_rx_data: RX parameters passed to the DMA engine
* @dma_tx_data: TX parameters passed to the DMA engine
* @rx_sgt: sg table for RX transfers
* @tx_sgt: sg table for TX transfers
* @zeropage: dummy page used as RX buffer when only TX buffer is passed in by
* the client
*
* This structure holds EP93xx SPI controller specific information. When
* @running is %true, driver accepts transfer requests from protocol drivers.
* @current_msg is used to hold pointer to the message that is currently
* processed. If @current_msg is %NULL, it means that no processing is going
* on.
*
* Most of the fields are only written once and they can be accessed without
* taking the @lock. Fields that are accessed concurrently are: @current_msg,
* @running, and @msg_queue.
*/
struct ep93xx_spi {
spinlock_t lock;
const struct platform_device *pdev;
struct clk *clk;
void __iomem *regs_base;
unsigned long sspdr_phys;
unsigned long min_rate;
unsigned long max_rate;
bool running;
struct workqueue_struct *wq;
struct work_struct msg_work;
struct completion wait;
struct list_head msg_queue;
struct spi_message *current_msg;
size_t tx;
size_t rx;
size_t fifo_level;
struct dma_chan *dma_rx;
struct dma_chan *dma_tx;
struct ep93xx_dma_data dma_rx_data;
struct ep93xx_dma_data dma_tx_data;
struct sg_table rx_sgt;
struct sg_table tx_sgt;
void *zeropage;
};
/**
* struct ep93xx_spi_chip - SPI device hardware settings
* @spi: back pointer to the SPI device
* @rate: max rate in hz this chip supports
* @div_cpsr: cpsr (pre-scaler) divider
* @div_scr: scr divider
* @dss: bits per word (4 - 16 bits)
* @ops: private chip operations
*
* This structure is used to store hardware register specific settings for each
* SPI device. Settings are written to hardware by function
* ep93xx_spi_chip_setup().
*/
struct ep93xx_spi_chip {
const struct spi_device *spi;
unsigned long rate;
u8 div_cpsr;
u8 div_scr;
u8 dss;
struct ep93xx_spi_chip_ops *ops;
};
/* converts bits per word to CR0.DSS value */
#define bits_per_word_to_dss(bpw) ((bpw) - 1)
static inline void
ep93xx_spi_write_u8(const struct ep93xx_spi *espi, u16 reg, u8 value)
{
__raw_writeb(value, espi->regs_base + reg);
}
static inline u8
ep93xx_spi_read_u8(const struct ep93xx_spi *spi, u16 reg)
{
return __raw_readb(spi->regs_base + reg);
}
static inline void
ep93xx_spi_write_u16(const struct ep93xx_spi *espi, u16 reg, u16 value)
{
__raw_writew(value, espi->regs_base