// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Driver for Broadcom BCM2835 SPI Controllers
*
* Copyright (C) 2012 Chris Boot
* Copyright (C) 2013 Stephen Warren
* Copyright (C) 2015 Martin Sperl
*
* This driver is inspired by:
* spi-ath79.c, Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
* spi-atmel.c, Copyright (C) 2006 Atmel Corporation
*/
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h> /* FIXME: using chip internals */
#include <linux/gpio/driver.h> /* FIXME: using chip internals */
#include <linux/of_irq.h>
#include <linux/spi/spi.h>
/* SPI register offsets */
#define BCM2835_SPI_CS 0x00
#define BCM2835_SPI_FIFO 0x04
#define BCM2835_SPI_CLK 0x08
#define BCM2835_SPI_DLEN 0x0c
#define BCM2835_SPI_LTOH 0x10
#define BCM2835_SPI_DC 0x14
/* Bitfields in CS */
#define BCM2835_SPI_CS_LEN_LONG 0x02000000
#define BCM2835_SPI_CS_DMA_LEN 0x01000000
#define BCM2835_SPI_CS_CSPOL2 0x00800000
#define BCM2835_SPI_CS_CSPOL1 0x00400000
#define BCM2835_SPI_CS_CSPOL0 0x00200000
#define BCM2835_SPI_CS_RXF 0x00100000
#define BCM2835_SPI_CS_RXR 0x00080000
#define BCM2835_SPI_CS_TXD 0x00040000
#define BCM2835_SPI_CS_RXD 0x00020000
#define BCM2835_SPI_CS_DONE 0x00010000
#define BCM2835_SPI_CS_LEN 0x00002000
#define BCM2835_SPI_CS_REN 0x00001000
#define BCM2835_SPI_CS_ADCS 0x00000800
#define BCM2835_SPI_CS_INTR 0x00000400
#define BCM2835_SPI_CS_INTD 0x00000200
#define BCM2835_SPI_CS_DMAEN 0x00000100
#define BCM2835_SPI_CS_TA 0x00000080
#define BCM2835_SPI_CS_CSPOL 0x00000040
#define BCM2835_SPI_CS_CLEAR_RX 0x00000020
#define BCM2835_SPI_CS_CLEAR_TX 0x00000010
#define BCM2835_SPI_CS_CPOL 0x00000008
#define BCM2835_SPI_CS_CPHA 0x00000004
#define BCM2835_SPI_CS_CS_10 0x00000002
#define BCM2835_SPI_CS_CS_01 0x00000001
#define BCM2835_SPI_FIFO_SIZE 64
#define BCM2835_SPI_FIFO_SIZE_3_4 48
#define BCM2835_SPI_DMA_MIN_LENGTH 96
#define BCM2835_SPI_NUM_CS 4 /* raise as necessary */
#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
| SPI_NO_CS | SPI_3WIRE)
#define DRV_NAME "spi-bcm2835"
/* define polling limits */
unsigned int polling_limit_us = 30;
module_param(polling_limit_us, uint, 0664);
MODULE_PARM_DESC(polling_limit_us,
"time in us to run a transfer in polling mode\n");
/**
* struct bcm2835_spi - BCM2835 SPI controller
* @regs: base address of register map
* @clk: core clock, divided to calculate serial clock
* @irq: interrupt, signals TX FIFO empty or RX FIFO ¾ full
* @tfr: SPI transfer currently processed
* @ctlr: SPI controller reverse lookup
* @tx_buf: pointer whence next transmitted byte is read
* @rx_buf: pointer where next received byte is written
* @tx_len: remaining bytes to transmit
* @rx_len: remaining bytes to receive
* @tx_prologue: bytes transmitted without DMA if first TX sglist entry's
* length is not a multiple of 4 (to overcome hardware limitation)
* @rx_prologue: bytes received without DMA if first RX sglist entry's
* length is not a multiple of 4 (to overcome hardware limitation)
* @tx_spillover: whether @tx_prologue spills over to second TX sglist entry
* @prepare_cs: precalculated CS register value for ->prepare_message()
* (uses slave-specific clock polarity and phase settings)