linux/drivers/spi/spi-davinci.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2009 Texas Instruments.
 * Copyright (C) 2010 EF Johnson Technologies
 */

#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/slab.h>

#include <linux/platform_data/spi-davinci.h>

#define CS_DEFAULT

#define SPIFMT_PHASE_MASK
#define SPIFMT_POLARITY_MASK
#define SPIFMT_DISTIMER_MASK
#define SPIFMT_SHIFTDIR_MASK
#define SPIFMT_WAITENA_MASK
#define SPIFMT_PARITYENA_MASK
#define SPIFMT_ODD_PARITY_MASK
#define SPIFMT_WDELAY_MASK
#define SPIFMT_WDELAY_SHIFT
#define SPIFMT_PRESCALE_SHIFT

/* SPIPC0 */
#define SPIPC0_DIFUN_MASK
#define SPIPC0_DOFUN_MASK
#define SPIPC0_CLKFUN_MASK
#define SPIPC0_SPIENA_MASK

#define SPIINT_MASKALL
#define SPIINT_MASKINT
#define SPI_INTLVL_1
#define SPI_INTLVL_0

/* SPIDAT1 (upper 16 bit defines) */
#define SPIDAT1_CSHOLD_MASK
#define SPIDAT1_WDEL

/* SPIGCR1 */
#define SPIGCR1_CLKMOD_MASK
#define SPIGCR1_MASTER_MASK
#define SPIGCR1_POWERDOWN_MASK
#define SPIGCR1_LOOPBACK_MASK
#define SPIGCR1_SPIENA_MASK

/* SPIBUF */
#define SPIBUF_TXFULL_MASK
#define SPIBUF_RXEMPTY_MASK

/* SPIDELAY */
#define SPIDELAY_C2TDELAY_SHIFT
#define SPIDELAY_C2TDELAY_MASK
#define SPIDELAY_T2CDELAY_SHIFT
#define SPIDELAY_T2CDELAY_MASK
#define SPIDELAY_T2EDELAY_SHIFT
#define SPIDELAY_T2EDELAY_MASK
#define SPIDELAY_C2EDELAY_SHIFT
#define SPIDELAY_C2EDELAY_MASK

/* Error Masks */
#define SPIFLG_DLEN_ERR_MASK
#define SPIFLG_TIMEOUT_MASK
#define SPIFLG_PARERR_MASK
#define SPIFLG_DESYNC_MASK
#define SPIFLG_BITERR_MASK
#define SPIFLG_OVRRUN_MASK
#define SPIFLG_BUF_INIT_ACTIVE_MASK
#define SPIFLG_ERROR_MASK

#define SPIINT_DMA_REQ_EN

/* SPI Controller registers */
#define SPIGCR0
#define SPIGCR1
#define SPIINT
#define SPILVL
#define SPIFLG
#define SPIPC0
#define SPIDAT1
#define SPIBUF
#define SPIDELAY
#define SPIDEF
#define SPIFMT0

#define DMA_MIN_BYTES

/* SPI Controller driver's private data. */
struct davinci_spi {};

static struct davinci_spi_config davinci_spi_default_cfg;

static void davinci_spi_rx_buf_u8(u32 data, struct davinci_spi *dspi)
{}

static void davinci_spi_rx_buf_u16(u32 data, struct davinci_spi *dspi)
{}

static u32 davinci_spi_tx_buf_u8(struct davinci_spi *dspi)
{}

static u32 davinci_spi_tx_buf_u16(struct davinci_spi *dspi)
{}

static inline void set_io_bits(void __iomem *addr, u32 bits)
{}

static inline void clear_io_bits(void __iomem *addr, u32 bits)
{}

/*
 * Interface to control the chip select signal
 */
static void davinci_spi_chipselect(struct spi_device *spi, int value)
{}

/**
 * davinci_spi_get_prescale - Calculates the correct prescale value
 * @dspi: the controller data
 * @max_speed_hz: the maximum rate the SPI clock can run at
 *
 * This function calculates the prescale value that generates a clock rate
 * less than or equal to the specified maximum.
 *
 * Returns: calculated prescale value for easy programming into SPI registers
 * or negative error number if valid prescalar cannot be updated.
 */
static inline int davinci_spi_get_prescale(struct davinci_spi *dspi,
							u32 max_speed_hz)
{}

/**
 * davinci_spi_setup_transfer - This functions will determine transfer method
 * @spi: spi device on which data transfer to be done
 * @t: spi transfer in which transfer info is filled
 *
 * This function determines data transfer method (8/16/32 bit transfer).
 * It will also set the SPI Clock Control register according to
 * SPI slave device freq.
 */
static int davinci_spi_setup_transfer(struct spi_device *spi,
		struct spi_transfer *t)
{}

static int davinci_spi_of_setup(struct spi_device *spi)
{}

/**
 * davinci_spi_setup - This functions will set default transfer method
 * @spi: spi device on which data transfer to be done
 *
 * This functions sets the default transfer method.
 */
static int davinci_spi_setup(struct spi_device *spi)
{}

static void davinci_spi_cleanup(struct spi_device *spi)
{}

static bool davinci_spi_can_dma(struct spi_controller *host,
				struct spi_device *spi,
				struct spi_transfer *xfer)
{}

static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status)
{}

/**
 * davinci_spi_process_events - check for and handle any SPI controller events
 * @dspi: the controller data
 *
 * This function will check the SPIFLG register and handle any events that are
 * detected there
 */
static int davinci_spi_process_events(struct davinci_spi *dspi)
{}

static void davinci_spi_dma_rx_callback(void *data)
{}

static void davinci_spi_dma_tx_callback(void *data)
{}

/**
 * davinci_spi_bufs - functions which will handle transfer data
 * @spi: spi device on which data transfer to be done
 * @t: spi transfer in which transfer info is filled
 *
 * This function will put data to be transferred into data register
 * of SPI controller and then wait until the completion will be marked
 * by the IRQ Handler.
 */
static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
{}

/**
 * dummy_thread_fn - dummy thread function
 * @irq: IRQ number for this SPI Master
 * @data: structure for SPI Master controller davinci_spi
 *
 * This is to satisfy the request_threaded_irq() API so that the irq
 * handler is called in interrupt context.
 */
static irqreturn_t dummy_thread_fn(s32 irq, void *data)
{}

/**
 * davinci_spi_irq - Interrupt handler for SPI Master Controller
 * @irq: IRQ number for this SPI Master
 * @data: structure for SPI Master controller davinci_spi
 *
 * ISR will determine that interrupt arrives either for READ or WRITE command.
 * According to command it will do the appropriate action. It will check
 * transfer length and if it is not zero then dispatch transfer command again.
 * If transfer length is zero then it will indicate the COMPLETION so that
 * davinci_spi_bufs function can go ahead.
 */
static irqreturn_t davinci_spi_irq(s32 irq, void *data)
{}

static int davinci_spi_request_dma(struct davinci_spi *dspi)
{}

#if defined(CONFIG_OF)

/* OF SPI data structure */
struct davinci_spi_of_data {};

static const struct davinci_spi_of_data dm6441_spi_data =;

static const struct davinci_spi_of_data da830_spi_data =;

static const struct davinci_spi_of_data keystone_spi_data =;

static const struct of_device_id davinci_spi_of_match[] =;
MODULE_DEVICE_TABLE(of, davinci_spi_of_match);

/**
 * spi_davinci_get_pdata - Get platform data from DTS binding
 * @pdev: ptr to platform data
 * @dspi: ptr to driver data
 *
 * Parses and populates pdata in dspi from device tree bindings.
 *
 * NOTE: Not all platform data params are supported currently.
 */
static int spi_davinci_get_pdata(struct platform_device *pdev,
			struct davinci_spi *dspi)
{}
#else
static int spi_davinci_get_pdata(struct platform_device *pdev,
			struct davinci_spi *dspi)
{
	return -ENODEV;
}
#endif

/**
 * davinci_spi_probe - probe function for SPI Master Controller
 * @pdev: platform_device structure which contains plateform specific data
 *
 * According to Linux Device Model this function will be invoked by Linux
 * with platform_device struct which contains the device specific info.
 * This function will map the SPI controller's memory, register IRQ,
 * Reset SPI controller and setting its registers to default value.
 * It will invoke spi_bitbang_start to create work queue so that client driver
 * can register transfer method to work queue.
 */
static int davinci_spi_probe(struct platform_device *pdev)
{}

/**
 * davinci_spi_remove - remove function for SPI Master Controller
 * @pdev: platform_device structure which contains plateform specific data
 *
 * This function will do the reverse action of davinci_spi_probe function
 * It will free the IRQ and SPI controller's memory region.
 * It will also call spi_bitbang_stop to destroy the work queue which was
 * created by spi_bitbang_start.
 */
static void davinci_spi_remove(struct platform_device *pdev)
{}

static struct platform_driver davinci_spi_driver =;
module_platform_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();